java.lang.IllegalStateException:未附加到上下文的片段
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java.lang.IllegalStateException:未附加到上下文的片段相关的知识,希望对你有一定的参考价值。
我的MainActivity中有一个带有viewpager的tablayout。
我的PagerAdapter
看起来像这样:
public class MainActivityPagerAdapter extends PagerAdapter {
public MainActivityPagerAdapter(FragmentManager fm, int numOfTabs) {
super(fm, numOfTabs);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new StoresFragment();
case 1:
return new OrdersFragment();
default:
return null;
}
}
}
我从另一个这样的活动回来了:
Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish(); //finishAffinity();
但后来我在MainActivity的viewpager中的一个片段中得到了一个java.lang.IllegalStateException
。
我阅读了许多相关问题并试图解决这个问题。据说,当一个人在PagerAdapter之外保留对Fragments的引用时就会发生这种情况。但我没有这样做,正如你在我的代码中看到的那样。
有谁知道我做错了什么?
编辑 - Stacktrace
FATAL EXCEPTION: main
Process: com.lifo.skipandgo, PID: 23665
java.lang.IllegalStateException: Fragment OrdersFragment{42c2a740} not attached to a context.
at android.support.v4.app.Fragment.requireContext(Fragment.java:614)
at android.support.v4.app.Fragment.getResources(Fragment.java:678)
at com.lifo.skipandgo.activities.fragments.OrdersFragment$1.results(OrdersFragment.java:111)
at com.lifo.skipandgo.connectors.firestore.QueryResult.receivedResult(QueryResult.java:37)
at com.lifo.skipandgo.controllers.UserController$2.onUpdate(UserController.java:88)
at com.lifo.skipandgo.connectors.firestore.QuerySubscription.onEvent(QuerySubscription.java:59)
at com.lifo.skipandgo.connectors.firestore.QuerySubscription.onEvent(QuerySubscription.java:18)
at com.google.firebase.firestore.zzg.onEvent(Unknown Source)
at com.google.firebase.firestore.g.zzh.zza(SourceFile:28)
at com.google.firebase.firestore.g.zzi.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5653)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
at dalvik.system.NativeStart.main(Native Method)
编辑:有趣的是,当错误发生时,视图已默认加载。因为错误发生在片段再次显示后大约10-15秒。我在我的orderFragment中,发生错误:
orders = new QueryResult<UserOrder>(UserOrder.class) {
@Override
public void results(List<UserOrder> results) {
orderLoadingMessage.setBackgroundColor(getResources().getColor(R.color.green));
}
}
我在onCreateView
中执行此操作,此结果在视图加载后大约10-15秒。
问题似乎是,您的片段正在侦听某些事件(通过UserController和QueryResult),并且在片段附加到上下文之前会触发这些事件。
尝试在片段分离时取消注册片段,并在连接后再次注册片段(LiveData也可以帮助解决这个问题)。另一种方法是在分离时接收和存储事件,并且仅在附加后处理它。
在片段与活动分离后,您的某些回调将被触发。要解决此问题,您需要检查是否添加了片段,然后再对任何回调执行操作。例如,将orders
对象的初始化更改为:
orders = new QueryResult<UserOrder>(UserOrder.class) {
@Override
public void results(List<UserOrder> results) {
if(isAdded()) {
orderLoadingMessage.setBackgroundColor(
getResources().getColor(R.color.green));
}
}
}
在我的情况下,这个异常发生在我展示DialogFragment
并称之为方法时。因为在调用方法之前片段没有附加到FragmentManager
(此操作异步完成),所以应用程序崩溃了。
val fragment = YourDialogFragment.newInstance()
fragment.show(fragmentManager, YourDialogFragment.TAG)
// This will throw an exception.
fragment.setCaptions("Yes", "No")
如果你用FragmentManager
添加片段,你会得到另一个exception:java.lang.IllegalArgumentException: No view found for id 0x1020002 (android:id/content) for fragment
(或类似的,如果你使用另一个id)。
你可以通过post
(或postDelayed
)调用片段方法,但这是一个糟糕的解决方案:
view?.post {
fragment.setCaptions("Yes", "No")
}
目前我使用childFragmentManager
而不是fragmentManager
:
val fragment = YourDialogFragment.newInstance()
fragment.show(childFragmentManager, YourDialogFragment.TAG)
fragment.setCaptions("Yes", "No")
我不记得我做了什么,但现在它有效。
你的解决方案
将你的getItem()方法更改为
switch (position) {
case 0:
return new StoresFragment();
case 1:
return new OrdersFragment();
default:
return null;
}
以上是关于java.lang.IllegalStateException:未附加到上下文的片段的主要内容,如果未能解决你的问题,请参考以下文章