1. 程式人生 > >ReactNative踩坑:封裝原生UI元件記憶體洩漏記錄

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);   
  }