ReactNative踩坑:封裝原生UI元件記憶體洩漏記錄
阿新 • • 發佈:2019-01-09
專案中初次使用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);
}