我有一个带有 Google 地图的活动和一个片段,其中包含地址(开始/停止)字段。
当
LocationManager
第一次返回用户位置时,我正在尝试更新地址片段中的起始字段。
但有时我会遇到例外:
java.lang.IllegalStateException:片段坐标片段未附加到活动
我不明白为什么。 我知道有方法
Fragment.isAdded()
,我可以使用,但这似乎不是解决问题的最佳方法。
有时我在尝试恢复状态时也会遇到此异常(在
onRestoreInstanceState(Bundle state)
中我获取数据并在onMapLoaded()
中尝试使用)
检查这个; http://developer.android.com/reference/android/app/Fragment.html#isAdded()
if(!isAdded()) {
return;
}
如果你可以使用 RxJava 2,你可以将 LocationManager 的结果缓存在 Observable 中,并且 Fragment 可以订阅该结果。
如果结果已到达,而Fragment尚未附加,则Fragment将在附加时收到结果。否则它会立即收到。
我建议您学习如何使用 RxJava 来解决此类问题。
private void setFragment(Fragment fragmentToSet, String tag) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
Fragment fragment = manager.findFragmentByTag(tag);
if (savedInstanceState == null) {
if (fragment != null && !fragment.isAdded()) {
transaction.replace(R.id.home_container, fragment, tag);
} else if (fragmentToSet != null && !fragmentToSet.isAdded()) {
transaction.replace(R.id.home_container, fragmentToSet, tag);
}
}else{
transaction.replace(R.id.home_container, fragment, tag);
}
transaction.commitAllowingStateLoss();
manager.executePendingTransactions();
}
尝试使用此函数在您的 Activity 中设置片段。它对我来说很有用。您可以从 Activity 的 onCreate 中保存保存的实例状态
虽然使用
isAdded()
是最简单的解决方案,但我遇到了使用此方法并不是最佳选择的情况。所以我采用了另一种方法:
首先,我创建了一个类型为
FragmentActivity
的全局变量。
然后,在
onViewCreated()
方法中,我像这样初始化了它的值:
fragmentActivity = requiredActivity();
之后,在
onAttach()
方法中,我将参数中的上下文强制转换为 FragmentActivity 并按以下方式将其分配给该全局变量:
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
this.fragmentActivity = (FragmentActivity) context;
}
以这种方式,我可以使用
requireActivity()
来代替使用 requireContext()
或 fragmentActivity
并避免 IllegalStateException。