22

こんにちは、私はこの問題に直面しています: Android アプリケーション (最小 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 を使用してフラグメントをテストします。

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

よくわからない場合は、お気軽にお問い合わせください。

4

4 に答える 4

1

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

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

于 2012-12-11T10:22:12.987 に答える
0

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

private static class MessagesAdapter extends CursorAdapter {
...

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

于 2012-03-12T16:35:46.140 に答える
0

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

于 2012-12-20T22:51:28.983 に答える