android 兼容性包 -fragment ...未附加到 Activity
你好, 我面临这个问题: 我正在使用兼容性包在 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;
}
以下是步骤崩溃前的应用程序:
- 活动在后台调用方法。
- 在 Activity 上调用回调方法
- 在此回调方法中,Activity 调用 Fragment
- 。 Fragment 尝试启动一些需要 Activity 的方法(如 getLoadManager())。
- 该片段不再附加到活动 => 我们尝试了两个修复
:
- 测试活动以检查活动是否正在完成(如上面的代码)
- 使用 isDetached 方法测试片段。
感谢您的帮助!!!
如果我不清楚,请随时向我询问更多信息。
Hello,
I'm facing this problem :
I'm using Compatibility package to use fragment in android application (min SDK 2.1).
An random exception occurs on fragment sometimes and I can't figure out why.
This is the stack trace I receive:
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)
Here is the corresponding code I'm calling in the Fragment class:
public class FeedListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor>, FeedListCursorAdapterListener {
...
public void refreshUpdateDate() {
getLoaderManager().restartLoader(LAST_UPDATE_CURSOR_ID, null, this);
}
...
}
Here is the code of the activity that calls the fragment:
private FeedListFragment mCursorLoaderListFg;
if (!isFinishing()) {
mCursorLoaderListFg.refreshUpdateDate();
mCursorLoaderListFg.refreshDisplay();
mCursorLoaderListFg.hideLoadingArticles();
}
Here is the fragment source code for 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;
}
Here are the steps of the application before crash:
- The activity calls methods in background.
- Callback methods are called on the activity
- In this callback method, the activity calls the fragment
- The fragment tries to launch some methods (like getLoadManager()) that need activity.
- The fragment is not attached anymore to the activity => crash
We tried two fixes:
- test on activity to check if the activity is finishing (like the code above)
- test on the fragment with the method isDetached.
Thanks for your help!!!
Do not hesitate to ask me more information if I'm not clear.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我有类似的问题。
尝试使用
isAdded()
或isVisible()
而不是isDetached()
。不幸的是,isDetached()
似乎并没有像它应该的那样工作......I had a similar problem.
Try using
isAdded()
orisVisible()
instead ofisDetached()
. Unfortunately,isDetached()
doesn't seem to work like it should...对我有用的是使用片段的片段侦听器,为其添加一个 getActivity 函数,该函数返回片段侦听器的活动(创建片段的活动)。
现在,当我接到需要该活动的电话时,我只需使用该功能。
What that worked for me was to use the Fragment listener of the fragment, add a getActivity function for it that returns the activity of the Fragment listener (the activity that created the fragment).
Now when i have a call that needed the activity i just use the function.
我通过将内部适配器类更改为静态内部类解决了这个问题。
我不知道如何解释这一点,但这与我们应该按照建议使用非静态内部类 此处
I resolved this issue by changing my inner adapter class to static inner class.
I am not sure how to explain that but it's related to the fact that we should avoir using non static inner class as recommended here
该片段将通过事件 Fragment.onAttach(Activity) 附加到活动。您的 Activity 必须实现 Fragment 提供的侦听器。
为了确保您的方法refreshUpdateDate()仅在事件发生后被调用,onAttach()应该首先将活动作为侦听器实现,然后调用侦听器fragmentAttached()方法。因此,当附加片段并且可以调用refreshUpdateDate()时,您的活动将收到通知,例如直接在fragmentAttached()中调用。
请参阅创建 Activity 的事件回调。
The fragment will be attached to the activity on the event Fragment.onAttach(Activity). Your Activity has to implement a listener, the Fragment provides.
To ensure that your method refreshUpdateDate() will be called only after the event, onAttach() should first take the activity as listener implementation and then call the listener fragmentAttached() method. So your activity will be informed, when the fragment is attached and refreshUpdateDate() can be called, for instance direct in fragmentAttached().
See Creating event callbacks to the activity.