web-dev-qa-db-ja.com

非常に単純なコードですが、フラグメントを使用すると「アクティビティが破棄されました」というエラーが発生します

私は非常に単純なActivityを作成しました。これは以下のような単純な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();
    }

}

私の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)
...

アクティビティが破壊されたなぜ???と文句を言う

追伸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>
21
Leem.fin

私も同様の問題に直面しました。
これは、FragmentTransaction.commit()を取得しようとしたときにアクティビティが破棄されたために発生したことに気付きました。

これに対する解決策は、Activity.isFinishing()がtrueかどうかをチェックすることでした。

if (!isFinishing()) {
  FragmentTransaction ft = getSupportFragmentManager()
     .beginTransaction();
  ft.replace(SOME_RES_ID, myFragmentInstance);
  ft.commit();
}
67
rishabhmhjn

私は自分自身を理解しました。それは、アクティビティのonCreate()メソッドでsuper.onCreate(savedInstanceState);を逃したためです。これを追加した後、問題はありません。

33
Leem.fin

私は同じ問題に直面し、それを修正することができませんでした。追加したイベントはisFinishing()チェックでもあります。しかし運はありません。

次に、もう1つのチェックisDestroyed()を追加し、正常に機能するようにしました。

if (!isFinishing() && !isDestroyed()) {
  FragmentTransaction ft = getSupportFragmentManager()
     .beginTransaction();
  ft.replace(LAYOUT_ID, myFragmentInstance);
  ft.commit();
}
12
vikoo

説明するには:

フレームワークはActivityを作成し、Activity.onCreate()を呼び出します。

Activity.onCreate()FragmentManagerに接続して、ホスティングアクティビティについて通知します。 Activity.onDestroy()は再び登録を解除します。

次に、Activityを拡張し、onCreate()をオーバーライドします。 toActivity.onCreate()を介さずにFragmentManagerを呼び出します。上記で説明した登録ロジック全体は実行されません。したがって、FragmentManagerはアクティビティについて何も認識せず、すでに破棄されていると想定し、誤解を招くエラーメッセージで例外を生成します。

4
sstn

この権利が正しく表示されていることを確認するために、MyActivityは、起動してFirstFragmentのインスタンスを追加しようとしているアクティビティです。

すぐに私はあなたが見る必要がある2つのことを見る

1)アクティビティでは、setContentView()またはsuper.onCreate()を呼び出すことはありません。最初の呼び出しは、レイアウトが膨らんだことがないため、R変数が存在しないため、大きな問題になる可能性があります。

2)MyActivityには独自のxmlレイアウトファイルが必要ですが、それはありません。

私がやったことは、コミットした直後です

fragmentManager.executePendingTransactions();

onpause()が呼び出された後はコミットしないでください

このアーティカルを読む フラグメントトランザクションとアクティビティ状態の損失

1
Asim Habib

それでも悪い、「アクティビティが破棄されました」というエラーが発生したため

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

だから私の解決策はチェックを追加することですif (!isFinishing()&&!isDestroyed())

_ if (!isFinishing()&&!isDestroyed()) {
                        fragmentTransaction.commitAllowingStateLoss();
                    }
                }
_
1
Serg Burlaka

似たような問題が発生した場合:

私は同じ問題に直面していましたが、私の場合、メインアクティビティからFragment1を呼び出していたため、ユーザーがFragment1レイアウトをクリックした場合、別のFragment2レイアウトを起動します。

メインアクティビティからFragment1を起動することはできましたが、Fragment1からFragment2に例外が発生しました"Activity has been destroy"

MainActivityクラスでFragmentManagerオブジェクトを静的として維持することにより、上記の問題を解決しました。プライベート静的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
Rohan J Mohite

super.onCreate(savedInstanceState)は、mFragments.attachHost(null /*parent*/);を呼び出すFragmentActivityのonCreateメソッドを呼び出します

この文は、FragmentTransaction.commit()を呼び出すと、FragmentControllerのmHostに値を割り当てます。

メソッドenqueueAction()では、この文があります

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

したがって、fragmentTransactionをコミットする前にsuper.onCreate(savedInstanceState)を呼び出さなかった場合、mHostがnullであるため、この例外が発生します。

0
dx3906