Butter Knife在項目中的一個小坑(解綁部分)

結論:

Butter Knife在進行unbind()操做的時候會把頁面的view引用置空。要注意一下bash

過程

今天項目在調試的時候忽然報了一個錯markdown

(請忽略包名)
01-20 21:35:18.737 29857-30181/com.amplitude.tron.volksradio22 E/Adreno-GSL: <gsl_memory_alloc_pure:1971>: GSL MEM ERROR: kgsl_sharedmem_alloc ioctl failed.
01-20 21:35:18.737 29857-30181/com.amplitude.tron.volksradio22 W/Adreno-GSL: <gsl_ldd_control:475>: ioctl fd 27 code 0x40080921 (IOCTL_KGSL_SHAREDMEM_FREE) failed: errno 22 Invalid argument
01-20 21:35:18.746 29857-30181/com.amplitude.tron.volksradio22 W/Adreno-GSL: <sharedmem_gpumem_alloc_id:2260>: sharedmem_gpumem_alloc: mmap failed errno 12 Out of memory
01-20 21:35:18.748 29857-30181/com.amplitude.tron.volksradio22 E/Adreno-GSL: <gsl_memory_alloc_pure:1971>: GSL MEM ERROR: kgsl_sharedmem_alloc ioctl failed.
01-20 21:35:18.757 29857-30181/com.amplitude.tron.volksradio22 W/Adreno-GSL: <sharedmem_gpumem_alloc_id:2260>: sharedmem_gpumem_alloc: mmap failed errno 12 Out of memory
01-20 21:35:18.759 29857-30181/com.amplitude.tron.volksradio22 E/Adreno-GSL: <gsl_memory_alloc_pure:1971>: GSL MEM ERROR: kgsl_sharedmem_alloc ioctl failed.
01-20 21:35:18.768 29857-30181/com.amplitude.tron.volksradio22 W/Adreno-GSL: <sharedmem_gpumem_alloc_id:2260>: sharedmem_gpumem_alloc: mmap failed errno 12 Out of memory
01-20 21:35:18.770 29857-30181/com.amplitude.tron.volksradio22 E/Adreno-GSL: <gsl_memory_alloc_pure:1971>: GSL MEM ERROR: kgsl_sharedmem_alloc ioctl failed.
01-20 21:35:18.770 29857-30181/com.amplitude.tron.volksradio22 W/Adreno-GSL: <gsl_ldd_control:475>: ioctl fd 27 code 0x40080921 (IOCTL_KGSL_SHAREDMEM_FREE) failed: errno 22 Invalid argument
01-20 21:35:18.778 29857-30181/com.amplitude.tron.volksradio22 E/OpenGLRenderer: GL error:  Out of memory!
複製代碼

有點蒙,就看出來了內存溢出。Google了一下,並無什麼有用信息。
着手分析(簡單記錄幾個步驟,撞牆的步驟就不寫了):ide

  1. 鎖定範圍
    因爲是Flutter項目,因此懷疑是路由問題,寫了一個跳轉,不斷點擊,沒有OOM
  2. 播放器問題,崩潰發生的頁面是一個播放器頁面。
    在原生頁面中找了一個場景,不斷跳轉並回退,沒有發生OOM。
  3. 此時已經有點接近崩潰,從新梳理問題。OOM,要麼申請了大內存,要麼就是泄漏了,看了一眼代碼
@Override
protected void onDestroy() {
    super.onDestroy();
    //log  -->2
    if (videoView != null) {
        videoView.release();
        //log  -->1
    }
}
複製代碼

明明有釋放呀,釋放的地方(1)加個log,竟然沒有打印,一度懷疑onDestroy沒有執行,在加log(2),有打印。 4. 貌似找到了有問題的點,確定是videoView爲null,看了一下super。this

@Override
protected void onDestroy() {
    if (mPresenter != null)
        mPresenter.detachView();
    super.onDestroy();
}

在看父類
@Override
protected void onDestroy() {
    super.onDestroy();
    mUnBinder.unbind();
}

看一下unbind(),注意是自動生成的實現類
@Override
@CallSuper
public void unbind() {
  LivePlayPreviewActivity target = this.target;
  if (target == null) throw new IllegalStateException("Bindings already cleared.");
  this.target = null;
  //就是這裏
  target.videoView = null;
}

複製代碼

在父類unbind的時候把view置空了,擦了一把汗,原來坑在這裏
Butter Knife在解綁的時候會把view的引用置空,哎! 調整一下代碼順序spa

@Override
protected void onDestroy() {
    if (videoView != null) {
        videoView.release();
    }
    super.onDestroy();
}
複製代碼

完美解決,提交!調試

相關文章
相關標籤/搜索