android 兼容性包 - 片段...未附加到 Activity

Posted

技术标签:

【中文标题】android 兼容性包 - 片段...未附加到 Activity【英文标题】:android compatibility package - fragment ... not attached to Activity 【发布时间】:2011-10-15 18:24:25 【问题描述】:

你好, 我面临这个问题: 我正在使用兼容性包在 android 应用程序中使用片段(最小 SDK 2.1)。

片段上有时会发生随机异常,我不知道为什么。 这是我收到的堆栈跟踪:

java.lang.IllegalStateException: Fragment FeedListFragment438a54e8 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);
    
...

这里是调用片段的activity的代码:

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;

以下是应用程序崩溃前的步骤:

    活动在后台调用方法。 在活动上调用回调方法 在这个回调方法中,activity调用了fragment 片段尝试启动一些需要活动的方法(如 getLoadManager())。 片段不再附加到活动 => 崩溃

我们尝试了两个修复:

测试活动以检查活动是否完成(如上面的代码) 使用方法 isDetached 对片段进行测试。

感谢您的帮助!!!

如果我不清楚,请随时向我询问更多信息。

【问题讨论】:

【参考方案1】:

我遇到了类似的问题。

尝试使用isAdded()isVisible() 而不是isDetached()。不幸的是,isDetached() 似乎无法正常工作......

【讨论】:

我会尝试你的解决方案并尽快给你反馈。感谢您的回答! 很棒的答案,检查 isAdded() 似乎解决了我的问题。这发生在我的 Nexus 7 上,同时快速改变方向。 就我而言,我在异步回调方法中调用 startActivity 时遇到了问题。这个 isAdded() 调用至少应该有助于防止崩溃。 永远不要从后台线程引用片段或活动。例如,如果您使用 AsyncTask,请将您的字符串传递给任务的构造函数或 execute() 方法。 当你的 Async 任务返回的数据被添加到 Fragment 时,就会发生崩溃,因为你的 Activity 没有附加并且崩溃【参考方案2】:

对我有用的是使用片段的片段侦听器,为其添加一个 getActivity 函数,该函数返回片段侦听器的活动(创建片段的活动)。

现在,当我有一个需要活动的呼叫时,我只需使用该功能。

【讨论】:

【参考方案3】:

我通过将内部适配器类更改为静态内部类解决了这个问题。

private static class MessagesAdapter extends CursorAdapter 
...

我不知道如何解释,但这与我们应该避免使用推荐的非静态内部类 here

【讨论】:

【参考方案4】:

片段将在事件 Fragment.onAttach(Activity) 上附加到活动。您的 Activity 必须实现 Fragment 提供的侦听器。 为确保您的方法 refreshUpdateDate() 仅在事件发生后被调用,onAttach() 应首先将活动作为侦听器实现,然后调用侦听器 fragmentAttached() 方法。因此,当附加片段并且可以调用 refreshUpdateDate() 时,将通知您的活动,例如直接在 fragmentAttached() 中。 见Creating event callbacks to the activity。

【讨论】:

以上是关于android 兼容性包 - 片段...未附加到 Activity的主要内容,如果未能解决你的问题,请参考以下文章

Fragment 未附加到 FragmentManager

如何重新附加片段(片段未附加到活动 Kotlin)

片段未附加到相应的片段

使用兼容包 android 膨胀片段

片段未附加到上下文

片段 MyFragment 未附加到 Activity