"Сбой доставки результата" - onActivityForResult
у меня есть LoginActivity
(пользователь). Это в основном его собственный Activity
это тема, как диалог (чтобы выглядеть как диалог). Он появляется над SherlockFragmentActivity
. То, что я хочу: если есть успешный вход, должно быть два FragmentTransaction
's, чтобы обновить представление. Вот код:
на LoginActivity
, в случае успешного входа,
setResult(1, new Intent());
на SherlockFragmentActivity
:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == 1) {
LoggedStatus = PrefActivity.getUserLoggedInStatus(this);
FragmentTransaction t = MainFragmentActivity.this.getSupportFragmentManager().beginTransaction();
SherlockListFragment mFrag = new MasterFragment();
t.replace(R.id.menu_frame, mFrag);
t.commit();
// Set up Main Screen
FragmentTransaction t2 = MainFragmentActivity.this.getSupportFragmentManager().beginTransaction();
SherlockListFragment mainFrag = new FeaturedFragment();
t2.replace(R.id.main_frag, mainFrag);
t2.commit();
}
}
он падает при первом фиксации, с этим LogCat:
E/AndroidRuntime(32072): Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
E/AndroidRuntime(32072): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299)
E/AndroidRuntime(32072): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310)
E/AndroidRuntime(32072): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541)
E/AndroidRuntime(32072): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525)
E/AndroidRuntime(32072): at com.kickinglettuce.rate_this.MainFragmentActivity.onActivityResult(MainFragmentActivity.java:243)
E/AndroidRuntime(32072): at android.app.Activity.dispatchActivityResult(Activity.java:5293)
E/AndroidRuntime(32072): at android.app.ActivityThread.deliverResults(ActivityThread.java:3315)
5 ответов:
прежде всего, вы должны прочитать мой блоге для получения дополнительной информации (это говорит о том, почему это исключение происходит, и что вы можете сделать, чтобы предотвратить это).
вызов
commitAllowingStateLoss()
это скорее Хак, чем исправление. Потери государства-это плохо, и их следует избегать любой ценой. В то время, что , состояние активности / фрагмента может еще не быть восстановлено, и поэтому любые транзакции, которые происходят в течение этого времени, будут потеряны в результате. Это очень важная ошибка, которую необходимо устранить! (Обратите внимание, что ошибка происходит только тогда, когда вашActivity
возвращается после того, как был убит системой... которые, в зависимости от того, сколько памяти в устройстве, случается редко... так что этот вид ошибки не то, что очень легко поймать во время тестирования).попробуйте переместить свои операции в
onPostResume()
вместо этого (обратите внимание, чтоonPostResume()
всегда вызывается послеonResume()
иonResume()
всегда вызывается послеonActivityResult()
):private boolean mReturningWithResult = false; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); mReturningWithResult = true; } @Override protected void onPostResume() { super.onPostResume(); if (mReturningWithResult) { // Commit your transactions here. } // Reset the boolean flag back to false for next time. mReturningWithResult = false; }
это может показаться немного странным, но это то, что необходимо для того, чтобы
FragmentTransaction
s всегда совершаются после theActivity
'S состояние было восстановлено в исходное состояние (onPostResume()
гарантированно вызывается послеActivity
состояние восстановлено).
Это похоже на ответ @Alex Lockwood, но с использованием
Runnable
:private Runnable mOnActivityResultTask; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); mOnActivityResultTask = new Runnable() { @Override public void run() { // Your code here } } } @Override protected void onPostResume() { super.onPostResume(); if (mOnActivityResultTask != null) { mOnActivityResultTask.run(); mOnActivityResultTask = null; } }
В случае, если вы используете Android 3.0 и лямбда используйте этот:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); mOnActivityResultTask = () -> { // Your code here } }
в моем случае я столкнулся с теми же проблемами, потому что следующее
public void onBackPressed() { super.onBackPressed(); setIntents(); } private void setIntents(){ Intent searchConstaints=new Intent(); searchConstaints.putExtra("min",20); searchConstaints.putExtra("max",80); setResult(101,searchConstaints); finish(); }
решается путем перестановки вызовов функций внутри onBackPressed()
public void onBackPressed() { setIntents(); super.onBackPressed(); }
можно использовать
ft.commitAllowingStateLoss()
чтобы решить эту проблему.причина: ваш
ft.commit()
метод был переключен послеonSaveInstanceState
.
ваш logcat четко говорит: "не удается выполнить это действие после onSaveInstanceState" -- ваш
Activity
уже мертв в этот момент и не может вернуть никаких результатов.просто двигаться:
Intent in = new Intent(); setResult(1, in);
к месту в вашем
Activity
где он еще жив, и все будет хорошо. и не забудьтеfinish()
кодActivity
для получения результата.