我有一个非常简单的Activity
:
public class ActivityLogin extends FragmentActivity {
/**
*
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_login);
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
FragmentManager fragmentManager = this.getSupportFragmentManager();
FragmentLogin fragment = (FragmentLogin) fragmentManager.findFragmentByTag(EnumFragmentTags.LOGIN.getValue());
if (fragment == null) {
Log.v("Activity", "Fragment is null");
fragment = new FragmentLogin();
fragmentManager.beginTransaction().add(R.id.login_layout, fragment, EnumFragmentTags.LOGIN.getValue()).commit();
} else {
Log.v("Activity", "Fragment is not null");
}
}
}
如您所见,我只创建Fragment
,如果它为空。 Fragment
不会保留实例:所以setRetainInstance(false)
。当我在后台工作并在我的this.getResources()
中拨打Fragment
时,我总是得到:
Fragment not attached to Activity
旋转设备后。如果我不旋转一切都很好。如果我旋转我得到上述错误。如果我使用this.getActivity.getResources()
而得到:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.support.v4.app.FragmentActivity.getResources()'
因此,由于某种原因,活动未附加到Fragment
。
为什么吗
我必须在我的Fragment上使用setRetainInstance(true)
才能使其正常工作吗?但我认为这样做会导致内存问题......
答案 0 :(得分:1)
当我在后台做一些工作并调用this.getResources()
时
这是你的问题。如果您在后台工作,并且Activity旋转(它被销毁并重新创建),则该片段不再附加到Activity,因此您会收到该错误。
一个简单的解决方案是在尝试访问Activity或资源之前检查您的片段是否仍然附着,并在分离时停止该工作,但更好的解决方案是将后台工作卸载到具有setRetainInstance的专用片段(真的)或服务。
基本上,您需要了解Activity生命周期,如果您旋转设备,则Activity和Fragment将被销毁并重新创建,但您仍然拥有初始Fragment实例,因为它具有一个隐含的后台任务参考片段,但片段不再附加。