问题
当应用程序在后台停留一段时间,并且安卓回收了最近显示的活动时,就会出现问题。带回应用程序会导致NullPointerException(NPE),因为activitys组件在初始化之前由片段调用(片段和活动都是同时重新创建的)。
解决方案
在BaseFragment类中引入了两种生命周期方法。
-
onInjectView()
调用以在onCreate(Bundle)上执行可选注入,如果抛出异常或返回false,则再次在onActivityCreated(Bundle)上调用该异常。在这种方法中,您可以获得注入组件并注入视图。Retrun true如果注射成功,则不会再次调用。
-
根据返回的值,调用第二个方法。方法名为
,因为它仅在片段已注入且注入的字段可以初始化时调用。
碱基片段
public abstract class BaseFragment extends Fragment {
private boolean mIsInjected = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
try {
mIsInjected = onInjectView();
} catch (IllegalStateException e) {
Log.e(e.getClass().getSimpleName(), e.getMessage());
mIsInjected = false;
}
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (mIsInjected) onViewInjected(savedInstanceState);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (!mIsInjected) {
mIsInjected = onInjectView();
if (mIsInjected) onViewInjected(savedInstanceState);
}
}
@SuppressWarnings("unchecked")
protected <C> C getComponent(Class<C> componentType) throws IllegalStateException {
C component = componentType.cast(((HasComponent<C>) getActivity()).getComponent());
if (component == null) {
throw new IllegalStateException(componentType.getSimpleName() + " has not been initialized yet.");
}
return component;
}
protected boolean onInjectView() throws IllegalStateException {
// Return false by default.
return false;
}
@CallSuper
protected void onViewInjected(Bundle savedInstanceState) {
// Intentionally left empty.
}
}
用法
public class SampleFragment extends BaseFragment implements SampleView {
@Inject
SamplePresenter mSamplePresenter;
@Override
protected boolean onInjectView() throws IllegalStateException {
getComponent(SampleComponent.class).inject(this);
return true;
}
@Override
protected void onViewInjected(Bundle savedInstanceState) {
super.onViewInjected(savedInstanceState);
this.mSamplePresenter.setView(this);
}
}
更多信息请访问
Efficient and bug-free fragment injection in Android MVP applications