ReactNative踩坑:封装原生UI组件内存泄漏记录

项目中初次使用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);   
  }

猜你喜欢

转载自blog.csdn.net/qq_15602635/article/details/79267804
今日推荐