Очень простой код, но получил ошибку "Активность была уничтожена" при использовании фрагмента
Я сделал очень простую активность, которая показывает простой список_файлов, как показано ниже:
Активность:
public class MyActivity extends FragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
FragmentManager fragMgr = getSupportFragmentManager();
FirstFragment list = new FirstFragment();
fragMgr.beginTransaction().add(android.R.id.content, list).commit();
}
}
My ListFragment:
public class FirstFragment extends ListFragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
inflater.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.main, null);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String listContent[] = {"Larry", "Moe", "Curly"};
setListAdapter(new ArrayAdapter<String>(getActivity(), R.layout.list_item, listContent));
}
...
}
Когда я запускаю свое приложение, у меня появилось сообщение :
java.lang.IllegalStateException: Activity has been destroyed
E/AndroidRuntime( 947): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
E/AndroidRuntime( 947): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
E/AndroidRuntime( 947): at android.app.ActivityThread.access$2200(ActivityThread.java:119)
E/AndroidRuntime( 947): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
E/AndroidRuntime( 947): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 947): at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 947): at android.app.ActivityThread.main(ActivityThread.java:4363)
E/AndroidRuntime( 947): at java.lang.reflect.Method.invokeNative(Native Method)
...
Он жалуется, что активность уничтожена, Почему???
P.S. main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="next" />
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#00FF00"
android:layout_weight="1"
android:drawSelectorOnTop="false" />
<TextView
android:id="@android:id/empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FF0000"
android:text="No data" />
</LinearLayout>
Ответы
Ответ 1
Я также столкнулся с аналогичной проблемой.
Я понял, что это произошло потому, что активность уничтожалась, а FragmentTransaction
собирался получить .commit()
.
Решением этого было проверить, истинно ли значение Activity.isFinishing()
или нет.
if (!isFinishing()) {
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
ft.replace(SOME_RES_ID, myFragmentInstance);
ft.commit();
}
Ответ 2
Я понял себя, это потому, что я пропустил super.onCreate(savedInstanceState);
в своем методе Activity onCreate(). Добавив это, все в порядке.
Ответ 3
Я столкнулся с той же проблемой и не смог ее исправить.
Событие, которое я добавил, также isFinishing(). но не повезло.
то я добавил еще одну проверку isDestroyed() и теперь ее работоспособность.
if (!isFinishing() && !isDestroyed()) {
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
ft.replace(LAYOUT_ID, myFragmentInstance);
ft.commit();
}
Ответ 4
Чтобы дать объяснение:
Структура создает Activity
и вызывает Activity.onCreate()
.
Activity.onCreate()
каким-то образом присоединяется к FragmentManager
, чтобы сообщить об активности хостинга. Activity.onDestroy()
снова отменит регистрацию.
Теперь вы расширяете Activity
и переопределяете onCreate()
. Вы звоните на FragmentManager
, не переходя к Activity.onCreate()
. Вся описанная выше логика регистрации не выполняется. Поэтому FragmentManager
ничего не знает об активности и предполагает, что он уже уничтожен и генерирует исключение с сообщением об ошибке.
Ответ 5
Чтобы убедиться, что я это правильно вижу, MyActivity - это активность, которую вы пытаетесь запустить, а затем добавить экземпляр FirstFragment в, правильно?
Сразу же я вижу две вещи, которые вам нужно посмотреть
1) В своей деятельности вы никогда не вызываете setContentView() или super.onCreate(). Первый вызов может быть огромной проблемой для вас, потому что это означает, что ваш макет никогда не накачивался, и поэтому переменная R не существует
2) MyActivity должен иметь свой собственный файл макета xml, которого у него нет.
Ответ 6
Все еще плохо, потому что получена ошибка "Активность была уничтожена"
ava.lang.IllegalStateException: Activity has been destroyed fragmentTransaction.commitAllowingStateLoss();
Итак, мое решение добавляет check if (!isFinishing()&&!isDestroyed())
if (!isFinishing()&&!isDestroyed()) {
fragmentTransaction.commitAllowingStateLoss();
}
}
Ответ 7
то, что я сделал, сразу после commit я call
fragmentManager.executePendingTransactions();
и никогда не пытайтесь совершать после onpause()
, называемого
Прочтите это Artical Фрагментные транзакции и потеря активности в деятельности
Ответ 8
super.onCreate(savedInstanceState) will call onCreate method in FragmentActivity,which will call mFragments.attachHost(null /*parent*/);
this sentence will assign a value to 'mHost' in FragmentController,when you calls FragmentTransaction.commit() ,
in the method 'enqueueAction()',it has this sentences
```
if (mDestroyed || mHost == null) {
throw new IllegalStateException("Activity has been destroyed");
}
```
so if you haven't call super.onCreate(savedInstanceState) before you commit a fragmentTransaction,you will get this exception because mHost is null
Ответ 9
Если кто-то сталкивается с подобным типом проблемы:
Мне приходилось сталкиваться с тем же вопросом, но в моем случае из Main Activity я звонил в Fragment1, а затем, если пользователь нажимает на Fragment1 Layout, я хочу запустить еще один макет Fragment2.
Мне удалось запустить Fragment1 из основной активности, но Fragment1 to Fragment2 он с ошибкой завершился с исключением: "Активность была уничтожена" .
Я решил проблему выше, сохранив объект FragmentManager как статический в классе MainActivity.
private static FragmentManager mfragmentManager = null;
вызов обоих фрагментов с использованием одного и того же выше объекта, разрешил мою проблему.
Ниже приведен код переключения фрагмента из основной операции.
public void switchToFragment(String fragmentName){
Fragment fragment = null;
switch (fragmentName) {
case "Fragment1":{
fragment = new Fragment1();
break;
}
case "Fragment2": {
fragment = new Fragment2();
break;
}
}
FragmentTransaction transaction = mfragmentManager.beginTransaction();
transaction.replace(R.id.fragment_container, fragment);
transaction.commit();
}