web-dev-qa-db-ja.com

android互換性パッケージ-フラグメント...アクティビティに添付されていません


こんにちは、私はこの問題に直面しています:Androidアプリケーション(min SDK 2.1)で互換性パッケージを使用してフラグメントを使用しています。

フラグメントでランダムな例外が発生することがあり、その理由を理解できません。これは私が受け取るスタックトレースです:

Java.lang.IllegalStateException: Fragment FeedListFragment{438a54e8} not attached to Activity
    at Android.support.v4.app.Fragment.getLoaderManager(Fragment.Java:715)
    at com.myappli.ui.FeedListFragment.refreshUpdateDate(FeedListFragment.Java:283)
    at com.myappli.ui.phone.FeedListActivity.onReceiveResult(FeedListActivity.Java:277)
    at com.myappli.data.rssplayer.service.KTDetachableResultReceiver.onReceiveResult(KTDetachableResultReceiver.Java:55)
    at Android.os.ResultReceiver$MyRunnable.run(ResultReceiver.Java:43)
    at Android.os.Handler.handleCallback(Handler.Java:587)
    at Android.os.Handler.dispatchMessage(Handler.Java:92)
    at Android.os.Looper.loop(Looper.Java:136)
    at Android.app.ActivityThread.main(ActivityThread.Java:4425)
    at Java.lang.reflect.Method.invokeNative(Native Method)
    at Java.lang.reflect.Method.invoke(Method.Java:521)
    at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:860)
    at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:618)
    at dalvik.system.NativeStart.main(Native Method)

Fragmentクラスで呼び出している対応するコードは次のとおりです。

public class FeedListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor>, FeedListCursorAdapterListener {

...
    public void refreshUpdateDate() {
    getLoaderManager().restartLoader(LAST_UPDATE_CURSOR_ID, null, this);
    }
...
}

フラグメントを呼び出すアクティビティのコードは次のとおりです。

private FeedListFragment mCursorLoaderListFg;

if (!isFinishing()) {
    mCursorLoaderListFg.refreshUpdateDate();
    mCursorLoaderListFg.refreshDisplay();
    mCursorLoaderListFg.hideLoadingArticles();
}

GetLoaderManager()のフラグメントソースコードは次のとおりです。

/**
* Return the LoaderManager for this fragment, creating it if needed.
*/
public LoaderManager getLoaderManager() {
    if (mLoaderManager != null) {
        return mLoaderManager;
    }
    if (mActivity == null) {
        throw new IllegalStateException("Fragment " + this + " not attached to Activity");
    }
    mCheckedForLoaderManager = true;
    mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, true);
    return mLoaderManager;
}

クラッシュする前のアプリケーションの手順は次のとおりです。

  1. アクティビティはバックグラウンドでメソッドを呼び出します。
  2. アクティビティでコールバックメソッドが呼び出されます
  3. このコールバックメソッドでは、アクティビティがフラグメントを呼び出します
  4. フラグメントは、アクティビティを必要とするいくつかのメソッド(getLoadManager()など)を起動しようとします。
  5. フラグメントはアクティビティにアタッチされなくなりました=>クラッシュ

2つの修正を試みました:

  • アクティビティをテストして、アクティビティが終了しているかどうかを確認します(上記のコードのように)
  • isDetachedメソッドを使用してフラグメントをテストします。

ご協力いただきありがとうございます!!!

不明な点がある場合は、遠慮なく詳細をお尋ねください。

22
Seynorth

同様の問題がありました。

isAdded()の代わりにisVisible()またはisDetached()を使用してみてください。残念ながら、isDetached()は正常に機能していないようです...

27
Pikaling

私にとってうまくいったのは、フラグメントのFragmentリスナーを使用し、Fragmentリスナーのアクティビティ(フラグメントを作成したアクティビティ)を返すgetActivity関数を追加することでした。

これで、アクティビティが必要な呼び出しがあったときに、関数を使用するだけです。

1
oznus

フラグメントは、イベントFragment.onAttach(Activity)のアクティビティに添付されます。アクティビティはリスナーを実装する必要があり、フラグメントが提供します。メソッドrefreshUpdateDate()がイベントの後でのみ呼び出されるようにするには、onAttach()が最初にアクティビティをリスナー実装として受け取り、次にリスナーfragmentAttached()メソッドを呼び出す必要があります。そのため、フラグメントが添付され、refreshUpdateDate()を呼び出すことができる場合、たとえばfragmentAttached()で直接、アクティビティに通知されます。 アクティビティへのイベントコールバックの作成 を参照してください。

内部アダプタクラスを静的内部クラスに変更することで、この問題を解決しました。

private static class MessagesAdapter extends CursorAdapter {
...

それを説明する方法はわかりませんが、推奨されるように非静的内部クラスを使用することを避けるべきであるという事実に関連しています here

0
Niqo