Очень простой код, но при использовании Fragment получена ошибка «Активность была уничтожена» - PullRequest
20 голосов
/ 03 февраля 2012

Я сделал очень простое действие , которое показывает простой ListFragment , как показано ниже:

Моя активность:

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();
    }

}

Мой списокFragment:

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>

Ответы [ 9 ]

67 голосов
/ 08 июня 2013

Я также столкнулся с подобной проблемой.
Я понял, что это произошло, потому что активность уничтожалась, когда FragmentTransaction собирался получить .commit().

Решением этой проблемы было проверитьявляется ли Activity.isFinishing() истинным или нет.

if (!isFinishing()) {
  FragmentTransaction ft = getSupportFragmentManager()
     .beginTransaction();
  ft.replace(SOME_RES_ID, myFragmentInstance);
  ft.commit();
}
32 голосов
/ 03 февраля 2012

Я сам понял, это потому, что я пропустил super.onCreate(savedInstanceState); в своем методе Activity onCreate ()После того, как добавил это, все в порядке.

12 голосов
/ 08 августа 2016

Я столкнулся с той же проблемой и не смог ее исправить.Событие, которое я добавил - это проверка isFinishing ().но не повезло.

тогда я добавил еще одну проверку isDestroyed () и теперь она работает нормально.

if (!isFinishing() && !isDestroyed()) {
  FragmentTransaction ft = getSupportFragmentManager()
     .beginTransaction();
  ft.replace(LAYOUT_ID, myFragmentInstance);
  ft.commit();
}
4 голосов
/ 18 февраля 2013

Чтобы дать объяснение:

Каркас создает Activity и вызывает Activity.onCreate().

Activity.onCreate() будет каким-либо образом подключаться к FragmentManager, чтобы сообщить ему о деятельности хостинга. Activity.onDestroy() снова отменит регистрацию.

Теперь вы расширяете Activity и переопределяете onCreate(). Вы делаете звонки на FragmentManager без звонка на Activity.onCreate(). Вся логика регистрации, описанная выше, не выполняется. Таким образом, FragmentManager ничего не знает об операции и предполагает, что она уже уничтожена, и генерирует исключение с вводящим в заблуждение сообщением об ошибке.

2 голосов
/ 03 февраля 2012

Просто чтобы убедиться, что я вижу это правильно, MyActivity - это действие, которое вы пытаетесь запустить, а затем добавить экземпляр FirstFragment, верно?

Сразу вижу две вещи, на которые нужно взглянуть

1) В своей деятельности вы никогда не вызываете setContentView () или super.onCreate (). Первый вызов может быть для вас огромной проблемой, потому что это означает, что ваш макет никогда не был раздут, и, следовательно, переменная R не существует

2) Для MyActivity необходим собственный файл макета xml, которого у него нет.

1 голос
/ 13 мая 2017

Все еще плохо, потому что получил ошибку «Деятельность была уничтожена»

ava.lang.IllegalStateException: Activity has been destroyed fragmentTransaction.commitAllowingStateLoss();

Поэтому мое решение - проверка на добавление if (!isFinishing()&&!isDestroyed())

 if (!isFinishing()&&!isDestroyed()) {
                        fragmentTransaction.commitAllowingStateLoss();
                    }
                }
1 голос
/ 21 января 2014

То, что я сделал, это сразу после коммита. Я звоню

fragmentManager.executePendingTransactions();

и никогда не пытаюсь сделать коммит после onpause(), вызванного

Прочитать этот художественный фрагментГосударственный убыток по сделкам и операциям

0 голосов
/ 16 апреля 2017

Если кто-то сталкивался с подобным типом проблемы:

Я столкнулся с тем же временем проблемы, но в моем случае из Main Activity я звонил Fragment1, а затем, если пользователь щелкнул на Fragment1 Layout, я хочу запустить еще один Fragment2 Layout.

Мне удалось запустить Fragment1 из основного действия, но Fragment1 to Fragment2 это было с ошибкой, за исключением: "Деятельность была уничтожена" .

Я решил вышеуказанную проблему, поддерживая объект FragmentManager как статический в классе MainActivity. приватный статический 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();
    }
0 голосов
/ 09 декабря 2016

super.onCreate (saveInstanceState) вызовет метод onCreate в FragmentActivity, который вызовет mFragments.attachHost(null /*parent*/);

Это предложение назначит значение для mHost во FragmentController, когда вы вызываете FragmentTransaction.commit (),

В методе enqueueAction() он имеет следующие предложения

 if (mDestroyed || mHost == null) {
        throw new IllegalStateException("Activity has been destroyed");
 }

Так что, если вы не вызывали super.onCreate (saveInstanceState) до совершения фрагмента транзакции, вы получите это исключение, поскольку mHost имеет значение null

...