项目中初次使用ReactNative,还是处在踩坑阶段。
偶然发现,多次打开首页页面会闪,打Log发现项目中封装给React Native使用的原生组件刷新了多次。再看对象实例,发现每次刷新都属于不同实例,内存泄漏了!!!
刷新监听的事件是 com.facebook.react.bridge.LifecycleEventListener.onHostResume()。也就是页面首次加载和activity resume的时候。
ViewManager示例代码:
public class SampleViewManager extends SimpleViewManager<SampleView> {
@Override
protected SampleView createViewInstance(ThemedReactContext reactContext) {
SampleView mSampleView = new SampleView(reactContext.getCurrentActivity());
reactContext.addLifecycleEventListener(mSampleView);
mSampleView.setReactContext(reactContext);
return mSampleView;
}
@Override
public String getName() {
return "SampleView";
}
}
View的代码
public class SampleView extends View implements LifecycleEventListener {
private ReactContext mReactContext;
public SampleView(Context context) {
super(context);
}
public void setReactContext(ReactContext reactContext){
mReactContext = reactContext;
}
@Override
public void onHostResume() {
refresh();
}
@Override
public void onHostPause() {
}
@Override
public void onHostDestroy() {
}
private void refresh(){
//do refresh
}
}
最后发现的问题就是 常见的一个内存泄漏:监听器内存泄漏。
ViewManager中
ReactContext.addLifecycleEventListener(mSampleView);
ReactContext持有了SampleView的引用,并且持有了activity的引用。且比activity生命周期更长。
解决问题也很简单,在合适的时机反注册监听器。那com.facebook.react.bridge.LifecycleEventListener.onHostDestroy()就是一个不错的时机,即activity onDestroy的时机。
@Override public void onHostDestroy() {
mReactContext.removeLifecycleEventListener(this);
}