Я использую библиотеку поддержки для моего приложения. В своей FragmentActivity я использую AsyncTask для загрузки данных из Интернета. В методе onPreExecute () я добавляю фрагмент, а в методе onPostExecute () я снова его удаляю. Когда ориентация меняется между ними, я получаю вышеупомянутое исключение. Пожалуйста, посмотрите на детали:
private class onFriendAddedAsyncTask extends AsyncTask<String, Void, String> {
DummyFragment dummyFragment;
FragmentManager fm;
FragmentTransaction ft;
@Override
protected void onPreExecute() {
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute");
dummyFragment = DummyFragment.newInstance();
fm = getSupportFragmentManager();
ft = fm.beginTransaction();
ft.add(dummyFragment, "dummy_fragment");
ft.commit();
}
@Override
protected void onPostExecute(String result) {
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute");
ft = fm.beginTransaction();
ft.remove(dummyFragment);
ft.commit();
}
@Override
protected String doInBackground(String... name) {
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/doInBackground");
...
}
Я получаю следующий LogCut:
01-05 23:54:19.958: V/MyFragmentActivity(12783): onFriendAddedAsyncTask/onPreExecute
01-05 23:54:19.968: V/DummyFragment(12783): onAttach
01-05 23:54:19.968: V/DummyFragment(12783): onCreate
01-05 23:54:19.968: V/MyFragmentActivity(12783): onFriendAddedAsyncTask/doInBackground
01-05 23:54:19.973: V/DummyFragment(12783): onCreateView
01-05 23:54:19.973: V/DummyFragment(12783): onActivityCreated
01-05 23:54:19.973: V/DummyFragment(12783): onStart
01-05 23:54:19.973: V/DummyFragment(12783): onResume
01-05 23:54:21.933: V/MyFragmentActivity(12783): onSaveInstanceState
01-05 23:54:21.933: V/DummyFragment(12783): onSaveInstanceState
01-05 23:54:21.933: V/MyFragmentActivity(12783): onPause
01-05 23:54:21.933: V/DummyFragment(12783): onPause
01-05 23:54:21.938: V/MyFragmentActivity(12783): onStop
01-05 23:54:21.938: V/DummyFragment(12783): onStop
01-05 23:54:21.938: V/MyFragmentActivity(12783): onDestroy
01-05 23:54:21.938: V/DummyFragment(12783): onDestroyView
01-05 23:54:21.938: V/DummyFragment(12783): onDestroy
01-05 23:54:21.938: V/DummyFragment(12783): onDetach
01-05 23:54:21.978: V/MyFragmentActivity(12783): onCreate
01-05 23:54:21.978: V/DummyFragment(12783): onAttach
01-05 23:54:21.978: V/DummyFragment(12783): onCreate
01-05 23:54:22.263: V/MyFragmentActivity(12783): onStart
01-05 23:54:22.313: V/DummyFragment(12783): onCreateView
01-05 23:54:22.313: V/DummyFragment(12783): onActivityCreated
01-05 23:54:22.313: V/DummyFragment(12783): onStart
01-05 23:54:22.323: V/MyFragmentActivity(12783): onResume
01-05 23:54:22.323: V/MyFragmentActivity(12783): onPostResume
01-05 23:54:22.323: V/MyFragmentActivity(12783): onResumeFragments
01-05 23:54:22.323: V/DummyFragment(12783): onResume
01-05 23:54:27.123: V/MyFragmentActivity(12783): onFriendAddedAsyncTask/onPostExecute
01-05 23:54:27.123: D/AndroidRuntime(12783): Shutting down VM
01-05 23:54:27.123: W/dalvikvm(12783): threadid=1: thread exiting with uncaught exception (group=0x4001d7d0)
01-05 23:54:27.138: E/AndroidRuntime(12783): FATAL EXCEPTION: main
01-05 23:54:27.138: E/AndroidRuntime(12783): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
01-05 23:54:27.138: E/AndroidRuntime(12783): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1314)
01-05 23:54:27.138: E/AndroidRuntime(12783): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1325)
01-05 23:54:27.138: E/AndroidRuntime(12783): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:548)
01-05 23:54:27.138: E/AndroidRuntime(12783): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:532)
01-05 23:54:27.138: E/AndroidRuntime(12783): at com.xyz.dummy.MyFragmentActivity$onFriendAddedAsyncTask.onPostExecute(MyFragmentActivity.java:447)
01-05 23:54:27.138: E/AndroidRuntime(12783): at com.xyz.dummy.MyFragmentActivity$onFriendAddedAsyncTask.onPostExecute(MyFragmentActivity.java:1)
01-05 23:54:27.138: E/AndroidRuntime(12783): at android.os.AsyncTask.finish(AsyncTask.java:417)
01-05 23:54:27.138: E/AndroidRuntime(12783): at android.os.AsyncTask.access$300(AsyncTask.java:127)
01-05 23:54:27.138: E/AndroidRuntime(12783): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
01-05 23:54:27.138: E/AndroidRuntime(12783): at android.os.Handler.dispatchMessage(Handler.java:99)
01-05 23:54:27.138: E/AndroidRuntime(12783): at android.os.Looper.loop(Looper.java:123)
01-05 23:54:27.138: E/AndroidRuntime(12783): at android.app.ActivityThread.main(ActivityThread.java:4627)
01-05 23:54:27.138: E/AndroidRuntime(12783): at java.lang.reflect.Method.invokeNative(Native Method)
01-05 23:54:27.138: E/AndroidRuntime(12783): at java.lang.reflect.Method.invoke(Method.java:521)
01-05 23:54:27.138: E/AndroidRuntime(12783): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
01-05 23:54:27.138: E/AndroidRuntime(12783): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
01-05 23:54:27.138: E/AndroidRuntime(12783): at dalvik.system.NativeStart.main(Native Method)
В других потоках о подобных проблемах причина, по-видимому, заключается в том, что метод onPostExecute вызывается до вызова метода onResume (). Но я получаю исключение, хотя onResume () вызывается раньше.
Кто-нибудь знает в чем дело?
Активность выглядит так:
public class MyFragmentActivity extends FragmentActivity implements OnFriendSelectedListener, OnFriendAddedListener, OnFriendOptionSelectedListener, LoaderCallbacks<Cursor> {
@Override
public void onCreate(Bundle savedInstanceState) {
Log.v("MyFragmentActivity", "onCreate");
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_activity_layout);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
FriendListFragment friendListFragment = (FriendListFragment)fm.findFragmentById(R.id.friend_list_fragment_layout);
if (friendListFragment == null) {
friendListFragment = new FriendListFragment();
ft.add(R.id.friend_list_fragment_layout, friendListFragment);
ft.commit();
fm.executePendingTransactions();
startService(new Intent(this, MyIntentService.class));
getSupportLoaderManager().initLoader(CHECK_EMPTY_DATABASE, null, this);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.fragment_activity_options_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case R.id.add_friend_menu_item:
AddFriendDialogFragment addFriendDialogFragment = AddFriendDialogFragment.newInstance();
addFriendDialogFragment.show(getSupportFragmentManager(), "add_friend_dialog_fragment");
return true;
default:
return false;
}
}
@Override
public void onFriendAdded(String name) {
name = name.trim();
if (name.length() > 0) {
new onFriendAddedAsyncTask().execute(name);
}
}
При использовании commitAllowingStateLoss () я получаю следующее исключение:
01-06 14:54:29.548: E/AndroidRuntime(18020): FATAL EXCEPTION: main
01-06 14:54:29.548: E/AndroidRuntime(18020): java.lang.IllegalStateException: Activity has been destroyed
01-06 14:54:29.548: E/AndroidRuntime(18020): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1329)
01-06 14:54:29.548: E/AndroidRuntime(18020): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:548)
01-06 14:54:29.548: E/AndroidRuntime(18020): at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:536)
01-06 14:54:29.548: E/AndroidRuntime(18020): at com.xyz.dummy.FadiaFragmentActivity$onFriendAddedAsyncTask.onPostExecute(FadiaFragmentActivity.java:461)
01-06 14:54:29.548: E/AndroidRuntime(18020): at com.xyz.dummy.FadiaFragmentActivity$onFriendAddedAsyncTask.onPostExecute(FadiaFragmentActivity.java:1)
01-06 14:54:29.548: E/AndroidRuntime(18020): at android.os.AsyncTask.finish(AsyncTask.java:417)
01-06 14:54:29.548: E/AndroidRuntime(18020): at android.os.AsyncTask.access$300(AsyncTask.java:127)
01-06 14:54:29.548: E/AndroidRuntime(18020): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
01-06 14:54:29.548: E/AndroidRuntime(18020): at android.os.Handler.dispatchMessage(Handler.java:99)
01-06 14:54:29.548: E/AndroidRuntime(18020): at android.os.Looper.loop(Looper.java:123)
01-06 14:54:29.548: E/AndroidRuntime(18020): at android.app.ActivityThread.main(ActivityThread.java:4627)
01-06 14:54:29.548: E/AndroidRuntime(18020): at java.lang.reflect.Method.invokeNative(Native Method)
01-06 14:54:29.548: E/AndroidRuntime(18020): at java.lang.reflect.Method.invoke(Method.java:521)
01-06 14:54:29.548: E/AndroidRuntime(18020): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
01-06 14:54:29.548: E/AndroidRuntime(18020): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
01-06 14:54:29.548: E/AndroidRuntime(18020): at dalvik.system.NativeStart.main(Native Method)
Я получаю то же IllegalStateExeption при реализации AsynTask следующим образом, потому что метод findFragmentById () возвращает нулевой указатель.
private class onFriendAddedAsyncTask extends AsyncTask<String, Void, String> {
protected void onPreExecute() {
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute");
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
DummyFragment dummyFragment = DummyFragment.newInstance();
ft.add(R.id.dummy_fragment_layout, dummyFragment);
ft.commit();
}
protected void onPostExecute(String result) {
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute");
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
DummyFragment dummyFragment = (DummyFragment) fm.findFragmentById(R.id.dummy_fragment_layout);
ft.remove(dummyFragment);
ft.commitAllowingStateLoss();
}
На следующем шаге я использую обработчик для добавления и удаления DummyFragment. Кроме того, я добавил еще несколько отладочных сообщений.
private class onFriendAddedAsyncTask extends AsyncTask<String, Void, String> {
@Override
protected void onPreExecute() {
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager());
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager().findFragmentById(R.id.dummy_fragment_layout));
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager().findFragmentById(R.id.friend_list_fragment_layout));
new Handler().post(new Runnable() {
public void run() {
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager());
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager().findFragmentById(R.id.dummy_fragment_layout));
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager().findFragmentById(R.id.friend_list_fragment_layout));
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
DummyFragment dummyFragment = DummyFragment.newInstance();
ft.add(R.id.dummy_fragment_layout, dummyFragment);
ft.commit();
}
});
@Override
protected void onPostExecute(String result) {
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager());
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager().findFragmentById(R.id.dummy_fragment_layout));
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager().findFragmentById(R.id.friend_list_fragment_layout));
new Handler().post(new Runnable() {
public void run() {
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager());
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager().findFragmentById(R.id.dummy_fragment_layout));
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager().findFragmentById(R.id.friend_list_fragment_layout));
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
DummyFragment dummyFragment = (DummyFragment) fm.findFragmentById(R.id.dummy_fragment_layout);
ft.remove(dummyFragment);
ft.commitAllowingStateLoss();
}
});
Я получаю следующий LogCut:
01-07 19:00:17.273: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute FragmentManager{45e384a8 in MyFragmentActivity{45e38358}}
01-07 19:00:17.273: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute null
01-07 19:00:17.273: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute FriendListFragment{45e38ab0 #0 id=0x7f0a0002}
01-07 19:00:17.283: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute FragmentManager{45e384a8 in MyFragmentActivity{45e38358}}
01-07 19:00:17.288: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/doInBackground
01-07 19:00:17.288: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute null
01-07 19:00:17.288: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute FriendListFragment{45e38ab0 #0 id=0x7f0a0002}
01-07 19:00:17.308: V/DummyFragment(4124): onAttach DummyFragment{45dd7498 #2 id=0x7f0a0004}
01-07 19:00:17.308: V/DummyFragment(4124): onCreate DummyFragment{45dd7498 #2 id=0x7f0a0004}
01-07 19:00:17.308: V/DummyFragment(4124): onCreateView DummyFragment{45dd7498 #2 id=0x7f0a0004}
01-07 19:00:17.308: V/DummyFragment(4124): onActivityCreated DummyFragment{45dd7498 #2 id=0x7f0a0004}
01-07 19:00:17.308: V/DummyFragment(4124): onStart DummyFragment{45dd7498 #2 id=0x7f0a0004}
01-07 19:00:17.313: V/DummyFragment(4124): onResume DummyFragment{45dd7498 #2 id=0x7f0a0004}
01-07 19:00:18.098: V/MyFragmentActivity(4124): onSaveInstanceState DummyFragment{45dd7498 #2 id=0x7f0a0004}
01-07 19:00:18.098: V/DummyFragment(4124): onSaveInstanceState DummyFragment{45dd7498 #2 id=0x7f0a0004}
01-07 19:00:18.098: V/MyFragmentActivity(4124): onPause DummyFragment{45dd7498 #2 id=0x7f0a0004}
01-07 19:00:18.098: V/DummyFragment(4124): onPause DummyFragment{45dd7498 #2 id=0x7f0a0004}
01-07 19:00:18.103: V/MyFragmentActivity(4124): onStop DummyFragment{45dd7498 #2 id=0x7f0a0004}
01-07 19:00:18.103: V/DummyFragment(4124): onStop DummyFragment{45dd7498 #2 id=0x7f0a0004}
01-07 19:00:18.103: V/MyFragmentActivity(4124): onDestroy DummyFragment{45dd7498 #2 id=0x7f0a0004}
01-07 19:00:18.103: V/DummyFragment(4124): onDestroyView DummyFragment{45dd7498 #2 id=0x7f0a0004}
01-07 19:00:18.108: V/DummyFragment(4124): onDestroy DummyFragment{45dd7498 #2 id=0x7f0a0004}
01-07 19:00:18.113: V/DummyFragment(4124): onDetach DummyFragment{45dd7498 #2 id=0x7f0a0004}
01-07 19:00:18.138: V/MyFragmentActivity(4124): onCreate
01-07 19:00:18.138: V/FriendListFragment(4124): FriendListFragment
01-07 19:00:18.138: V/FriendListFragment(4124): onAttach FriendListFragment{45e4a7f8 #0 id=0x7f0a0002}
01-07 19:00:18.138: V/FriendListFragment(4124): onCreate FriendListFragment{45e4a7f8 #0 id=0x7f0a0002}
01-07 19:00:18.148: V/DummyFragment(4124): onAttach DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
01-07 19:00:18.153: V/DummyFragment(4124): onCreate DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
01-07 19:00:18.523: V/MyFragmentActivity(4124): onStart DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
01-07 19:00:18.543: V/FriendListFragment(4124): onActivityCreated FriendListFragment{45e4a7f8 #0 id=0x7f0a0002}
01-07 19:00:18.548: V/DummyFragment(4124): onCreateView DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
01-07 19:00:18.548: V/DummyFragment(4124): onActivityCreated DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
01-07 19:00:18.548: V/FriendListFragment(4124): onLoadFinished FragmentManager{45d8e478 in MyFragmentActivity{45e4a6d8}}
01-07 19:00:18.548: V/FriendListFragment(4124): onLoadFinished FriendListFragment{45e4a7f8 #0 id=0x7f0a0002}
01-07 19:00:18.553: V/DummyFragment(4124): onStart DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
01-07 19:00:18.553: V/FriendListFragment(4124): onLoadFinished FragmentManager{45d8e478 in MyFragmentActivity{45e4a6d8}}
01-07 19:00:18.553: V/FriendListFragment(4124): onLoadFinished FriendListFragment{45e4a7f8 #0 id=0x7f0a0002}
01-07 19:00:18.558: V/MyFragmentActivity(4124): onResume DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
01-07 19:00:18.558: V/MyFragmentActivity(4124): onPostResume DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
01-07 19:00:18.558: V/MyFragmentActivity(4124): onResumeFragments DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
01-07 19:00:18.558: V/FriendListFragment(4124): onResume FriendListFragment{45e4a7f8 #0 id=0x7f0a0002}
01-07 19:00:18.563: V/FriendListFragment(4124): onCreateLoader FriendListFragment{45e4a7f8 #0 id=0x7f0a0002}
01-07 19:00:18.563: V/DummyFragment(4124): onResume DummyFragment{45d7d1a0 #2 id=0x7f0a0004}
01-07 19:00:18.723: V/FriendListFragment(4124): onLoadFinished FragmentManager{45d8e478 in MyFragmentActivity{45e4a6d8}}
01-07 19:00:18.723: V/FriendListFragment(4124): onLoadFinished FriendListFragment{45e4a7f8 #0 id=0x7f0a0002}
01-07 19:00:18.893: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute FragmentManager{45e384a8 in null}}
01-07 19:00:18.893: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute null
01-07 19:00:18.893: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute null
01-07 19:00:18.923: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute FragmentManager{45e384a8 in null}}
01-07 19:00:18.923: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute null
01-07 19:00:18.923: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute null
01-07 19:00:18.928: D/AndroidRuntime(4124): Shutting down VM
01-07 19:00:18.928: W/dalvikvm(4124): threadid=1: thread exiting with uncaught exception (group=0x4001d7d0)
01-07 19:00:18.938: E/AndroidRuntime(4124): FATAL EXCEPTION: main
01-07 19:00:18.938: E/AndroidRuntime(4124): java.lang.IllegalStateException: Activity has been destroyed
01-07 19:00:18.938: E/AndroidRuntime(4124): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1329)
01-07 19:00:18.938: E/AndroidRuntime(4124): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:548)
01-07 19:00:18.938: E/AndroidRuntime(4124): at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:536)
01-07 19:00:18.938: E/AndroidRuntime(4124): at com.xyz.dummy.MyFragmentActivity$onFriendAddedAsyncTask$2.run(MyFragmentActivity.java:476)
01-07 19:00:18.938: E/AndroidRuntime(4124): at android.os.Handler.handleCallback(Handler.java:587)
01-07 19:00:18.938: E/AndroidRuntime(4124): at android.os.Handler.dispatchMessage(Handler.java:92)
01-07 19:00:18.938: E/AndroidRuntime(4124): at android.os.Looper.loop(Looper.java:123)
01-07 19:00:18.938: E/AndroidRuntime(4124): at android.app.ActivityThread.main(ActivityThread.java:4627)
01-07 19:00:18.938: E/AndroidRuntime(4124): at java.lang.reflect.Method.invokeNative(Native Method)
01-07 19:00:18.938: E/AndroidRuntime(4124): at java.lang.reflect.Method.invoke(Method.java:521)
01-07 19:00:18.938: E/AndroidRuntime(4124): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
01-07 19:00:18.938: E/AndroidRuntime(4124): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
01-07 19:00:18.938: E/AndroidRuntime(4124): at dalvik.system.NativeStart.main(Native Method)
В onPreExecute () FriendListFragment имеет идентификатор = 0x7f0a0002. Внутри обработчика DummyFragment создается с id = 0x7f0a0004. В onPostExecute () оба идентификатора равны нулю. В onPreExecute () адрес MyFragmentActivity - 45e38358. но в onPostExecute () он является нулевым. Но в обоих методах адрес FragmentManager - 45e384a8. Я предполагаю, что onPostExecute использует недопустимый FragmentManager. Но почему?
Ответы:
Вы должны сделать транзакцию
Handler
следующим образом:источник
private static WeakReference<FragmentActivity> mActivity = null;
WeakReference
предотвращает утечку действия ... вам нужно позвонить,mActivity.get()
чтобы получить экземпляр, и оно будет нулевым, если действие было уничтожено. Чтобы обновить его, вам нужно написатьmActivity = new WeakReference<FragmentActivity>(this);
- в хорошем местеonCreate()
- что обновит ссылку.Спасибо Олегу Васкевичу. Используя
WeakReference
изFragmentActivity
решить эту проблему. Мой код выглядит следующим образом:источник
MyFragmentActivity mActivity = this ?
Без статических и слабых ссылокЯ считаю, что правильный ответ на этот вопрос заключается в следующем методе.
Приведенное выше описание относится к этому способу.
Эта проблема возникает именно тогда, когда устройство переходит в режим сна.
http://developer.android.com/reference/android/app/FragmentTransaction.html
источник
Краткое и рабочее решение:
Следуйте простым шагам:
Шаг 1 : Переопределить
onSaveInstanceState
состояние в соответствующем фрагменте. И удалите супер метод из него.Шаг 2 : Используйте
CommitAllowingStateLoss();
вместо операцийcommit();
while фрагмент.источник
Проверьте, если активность,
isFinishing()
прежде чем показывать фрагмент.Пример:
источник
У меня была похожая проблема, которую я исправил, переместив фрагмент кода транзакции из
onResume()
вonStart()
.Чтобы быть более точным: мое приложение запуска. После нажатия кнопки «Домой» на Android пользователь может выбрать средство запуска, пока его / ее решение не запомнится. При переходе «назад» в этот момент (например, нажав в сероватой области) приложение зависло.
Может быть, это кому-нибудь поможет.
источник
Используйте
commitAllowingStateLoss()
вместоcommit()
.при использовании
commit()
он может выдать исключение, если происходит потеря состояния, ноcommitAllowingStateLoss()
сохраняет транзакцию без потери состояния, чтобы не вызывать исключение в случае потери состояния.источник
Это произошло для меня, потому что я вызывал
commit()
субфрагмент, который пропускал активность. Он сохранил активность как свойство, а переменная активности ротации не была обновлена,onAttach();
поэтому я пытался зафиксировать транзакцию в активности зомби по сохраненному(setRetainInstance(true);)
фрагменту.источник
Причина исключения является повторным созданием
FragmentActivity
во время выполнения изAsyncTask
и доступа к предыдущему, разрушенномуFragmentActivity
вonPostExecute()
потом.Проблема в том, чтобы получить действительную ссылку на новое
FragmentActivity
. Там нет способа для этого ниgetActivity()
ниfindById()
или что - то подобное. Этот форум полон тем по этой проблеме (например, поиск по"Activity context in onPostExecute"
). Некоторые из них описывают обходные пути (до сих пор я не нашел хорошего).Возможно, было бы лучшим решением использовать Сервис для моих целей.
источник
Существует одно альтернативное решение (НЕ лучшее решение) для этой проблемы, но оно работает. С помощью флага вы можете справиться с этим, как показано ниже
И вы можете проверить это
boolean
значение при выполнении фрагмента транзакции.источник
Для чего это стоит; У меня была эта ошибка в приложении, которое запускало службы в фоновом режиме. На одном из них диалоговое окно тайм-аута должно было быть показано пользователю. Этот диалог был причиной возникновения этой ошибки, если приложение больше не работало на переднем плане.
В нашем случае показ диалога был бесполезен, когда приложение находилось в фоновом режиме, поэтому мы просто отслеживали его (логическое значение onPause en onResume), а затем отображали диалоговое окно только тогда, когда приложение действительно видимо для пользователя.
источник
Решение 1: переопределить
onSaveInstanceState()
и удалить в нем супер-вызов.Решение 2: переопределить
onSaveInstanceState()
и удалить свой фрагмент перед супер вызовомисточник
Эта проблема возникает, когда процесс пытается манипулировать действием,
onStop()
которое было вызвано. Он не обязательно привязан к фрагментной транзакции, но также и к другим методам, таким как onBackPressed ().В дополнение к AsyncTask, другим источником такой проблемы является неправильное размещение подписки шаблона шины. Обычно подписка на Event Bus или RxBus регистрируется во время действия onCreate и отменяется в onDestroy. Если новое действие начинается и публикует событие, перехваченное подписчиками из предыдущего действия, то это может привести к этой ошибке. Если это произойдет, то одним из решений будет перемещение регистрации и отмены регистрации подписки в
onStart()
иonStop()
.источник
Это решило мою проблему: Кодлин Kotlin:
Чем это
commitAllowingStateLoss()
отличается отcommit()
?Согласно документации:
Нравится,
commit()
но позволяет выполнить коммит после сохранения состояния действия. https://developer.android.com/reference/android/app/FragmentTransaction#commitAllowingStateLoss ()PS: вы можете показать Fragment Dialogs или можете загружать фрагменты этим методом. Применимо для обоих.
источник
У моего приложения есть фрагмент для загрузки в течение 3 секунд, но когда первый экран готовится к показу, я нажимаю кнопку «Домой» и возобновляю его запуск, он показывает ту же ошибку, поэтому он редактирует мой код и работает очень гладко:
ПРИМЕЧАНИЕ: добавьте commitAllowingStateLoss () вместо commit ()
источник
Начиная с версии 24.0.0 библиотеки поддержки, вы можете вызвать
FragmentTransaction.commitNow()
метод, который синхронно фиксирует эту транзакцию, вместо вызова сcommit()
последующимexecutePendingTransactions()
источник
IllegalStateException встречается, если вы фиксируете какую-либо фрагментную транзакцию после того, как активность потеряла свое состояние. Активность не находится на переднем плане. Это часто встречается при попытке зафиксировать любой фрагмент в AsyncTask или после сетевого запроса.
Чтобы избежать этого сбоя, вам просто нужно отложить любую транзакцию фрагмента, пока состояние активности не будет восстановлено. Вот как это делается
Объявите две частные логические переменные
Теперь в onPostResume () и onPause мы устанавливаем и удаляем нашу логическую переменную isTransactionSafe. Идея состоит в том, чтобы помечать транзакции как безопасные только тогда, когда активность находится на переднем плане, поэтому нет шансов потерять состояние.
То, что мы сделали до сих пор, спасет от IllegalStateException, но наши транзакции будут потеряны, если они будут выполнены после того, как действие переместится в фоновый режим, что-то вроде commitAllowStateloss (). Чтобы помочь с этим, у нас есть логическая переменная isTransactionPending
В этой статье довольно подробно объясняется, почему встречается это исключение, и сравниваются различные методы для его устранения. Настоятельно рекомендуется
источник
У меня было то же исключение, и я попробовал много фрагментов, которые я нашел здесь в этом обсуждении потока стека, но никакие фрагменты не работали для меня.
Но мне удалось решить все вопросы, я поделюсь с вами решениями:
В первой части: я пытался показать DialogFragment в Activity, но из другого Java-класса. Затем, проверив атрибут этого экземпляра, я обнаружил, что это был старый экземпляр Activity, а не текущий запущенный Activity. [Более точно, я использовал socket.io, и я забыл сделать socket.off («пример», пример) ... так, чтобы он был привязан к старому экземпляру действия. ]
Во второй части: я пытался показать DialogFragment в Activity, когда возвращаюсь к нему с намерением, но когда я проверял свои журналы, я видел, что когда он пытался показать фрагмент, действие все еще не было в методе onStart , так что это привело к сбою приложения, потому что он не нашел класс Activity, чтобы показать фрагмент на нем.
Несколько советов: проверьте с некоторыми атрибутами, если вы не используете старый экземпляр своей активности, с которым вы пытаетесь показать свой фрагмент, или проверьте жизненный цикл своей активности, прежде чем показывать свой фрагмент, и убедитесь, что вы находитесь в onStart или onResume, прежде чем показывать его. ,
Я надеюсь, что эти объяснения помогут вам.
источник