"Ошибка выполнения результата" - onActivityForResult
У меня есть LoginActivity
(Вход пользователя). Это, в основном, его собственный Activity
, который называется как диалог (чтобы выглядеть как диалог). Он появляется над SherlockFragmentActivity
. Я хочу: если есть успешный вход в систему, для обновления представления должно быть два FragmentTransaction
. Вот код:
В LoginActivity
, если успешный вход в систему,
setResult(1, new Intent());
В SherlockFragmentActvity
:
@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)
Ответы
Ответ 1
Прежде всего, вы должны прочитать мою сообщение в блоге для получения дополнительной информации (это говорит о том, почему это исключение происходит и что вы можете сделать, чтобы предотвратить его).
Вызов commitAllowingStateLoss()
- это скорее взлом, чем исправление. Государственная потеря плохая и ее следует избегать любой ценой. Во время вызова onActivityResult()
состояние активности/фрагмента может быть еще не восстановлено, и поэтому любые транзакции, которые происходят в течение этого времени, будут потеряны в результате. Это очень важная ошибка, которая должна быть решена! (Обратите внимание, что ошибка возникает только тогда, когда ваш 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
всегда выполнялся после того, как состояние Activity
было восстановлено в исходное состояние (onPostResume()
гарантированно будет вызвано после восстановления состояния Activity
).
Ответ 2
Это похоже на ответ @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 и выше с lambdas, используйте это:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
mOnActivityResultTask = () -> {
// Your code here
}
}
Ответ 3
В моем случае я столкнулся с теми же проблемами из-за следующих
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();
}
Ответ 4
ваш логарифм четко говорит: "Невозможно выполнить это действие после onSaveInstanceState" - ваш Activity
уже мертв в этой точке и не смог вернуть никаких результатов.
просто переместите:
Intent in = new Intent();
setResult(1, in);
к месту в вашем Activity
, где он все еще жив, и все будет хорошо.
и не забывайте finish()
ваш Activity
, чтобы доставить результат.
Ответ 5
Вы можете использовать ft.commitAllowingStateLoss()
для решения этой проблемы.
Причина: ваш метод ft.commit()
был переключен после onSaveInstanceState
.