Explorar el Código

LVCircularRing内存泄露

詹子聪 hace 5 años
padre
commit
9a6e15fda3

+ 12 - 9
app/src/main/java/com/miekir/newmvp/TestPresenter.java

@@ -1,9 +1,9 @@
 package com.miekir.newmvp;
 
-import com.miekir.mvp.bean.DataResult;
-import com.miekir.mvp.jetpack.ResultLiveData;
+import android.util.Log;
+
+import com.miekir.mvp.jetpack.BeanLiveData;
 import com.miekir.mvp.presenter.BasePresenter;
-import com.miekir.mvp.jetpack.MvpLiveData;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -22,15 +22,19 @@ public class TestPresenter extends BasePresenter {
 
     }
 
-    public ResultLiveData<List<TestBean1>> go() {
-        showLoading();
-        final ResultLiveData<List<TestBean1>> specificLiveData = new ResultLiveData<>();
+    public BeanLiveData<List<TestBean1>> go() {
+        final BeanLiveData<List<TestBean1>> specificLiveData = getLiveData(true);
 
         new Thread(new Runnable() {
             @Override
             public void run() {
                 try {
-                    Thread.sleep(5000);
+
+                    for (int i = 0; i < 20; i++) {
+                        Thread.sleep(1000);
+                        Log.i("test", "io thread..." + i);
+                    }
+
                     TestBean1 bean = new TestBean1(3, "ViewModel Jason");
                     List<TestBean1> list = new ArrayList<>();
                     list.add(bean);
@@ -38,7 +42,6 @@ public class TestPresenter extends BasePresenter {
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
-                dismissLoading();
             }
         }).start();
 
@@ -47,6 +50,6 @@ public class TestPresenter extends BasePresenter {
 
     @Override
     public void onTaskCancel() {
-
+        super.onTaskCancel();
     }
 }

+ 16 - 1
mvp/src/main/java/com/miekir/mvp/jetpack/ResultLiveData.java

@@ -2,6 +2,7 @@ package com.miekir.mvp.jetpack;
 
 import com.miekir.mvp.bean.DataResult;
 import com.miekir.mvp.constant.BaseMvpResponse;
+import com.miekir.mvp.presenter.BasePresenter;
 
 /**
  * Copyright (C), 2019-2020, Miekir
@@ -10,8 +11,22 @@ import com.miekir.mvp.constant.BaseMvpResponse;
  * @date 2020/11/14 21:36
  * Description:
  */
-public class ResultLiveData<D> extends MvpLiveData<DataResult<D>> {
+public class BeanLiveData<D> extends MvpLiveData<DataResult<D>> {
+
+    public BeanLiveData(BasePresenter mPresenter, boolean mWidthDialog) {
+        super(mPresenter, mWidthDialog);
+    }
+
     public void post(int responseCode, String message, D dataBean) {
+        if (mPresenter == null) {
+            return;
+        }
+
+        if (mWidthDialog) {
+            mPresenter.dismissLoading();
+        }
+
+        mPresenter.getLiveDataList().remove(this);
         postValue(new DataResult<D>(responseCode, message, dataBean));
     }
 

+ 18 - 0
mvp/src/main/java/com/miekir/mvp/jetpack/MvpLiveData.java

@@ -3,6 +3,7 @@ package com.miekir.mvp.jetpack;
 import androidx.lifecycle.MutableLiveData;
 import com.miekir.mvp.bean.DataResult;
 import com.miekir.mvp.constant.BaseMvpResponse;
+import com.miekir.mvp.presenter.BasePresenter;
 
 //得到一个LiveData,用于传递Observer参数的形式,这里暂时用不到
 //private <T> MutableLiveData<T> observeOnce(final Observer<T> observer) {
@@ -24,11 +25,28 @@ import com.miekir.mvp.constant.BaseMvpResponse;
  * Description:
  */
 public class MvpLiveData<T> extends MutableLiveData<T> {
+    protected BasePresenter mPresenter;
+    protected boolean mWidthDialog;
+
+    public MvpLiveData(BasePresenter mPresenter, boolean mWidthDialog) {
+        this.mPresenter = mPresenter;
+        this.mWidthDialog = mWidthDialog;
+    }
+
+    private MvpObserver<T> mObserver;
+    public void cancelObserve() {
+        removeObserver(mObserver);
+        mObserver.setLiveData(null);
+        mObserver = null;
+        mPresenter = null;
+    }
+
     /**
      * 只监听一次的LiveData
      * @param observer
      */
     public void observeOnce(MvpObserver<T> observer) {
+        mObserver = observer;
         observer.setLiveData(this);
         observeForever(observer);
     }

+ 2 - 2
mvp/src/main/java/com/miekir/mvp/jetpack/MvpObserver.java

@@ -24,8 +24,8 @@ public abstract class MvpObserver<T> implements Observer<T> {
     @Override
     public void onChanged(T t) {
         if (liveData != null) {
-            liveData.removeObserver(this);
+            liveData.cancelObserve();
+            onDataChanged(t);
         }
-        onDataChanged(t);
     }
 }

+ 32 - 13
mvp/src/main/java/com/miekir/mvp/presenter/BasePresenter.java

@@ -1,14 +1,12 @@
 package com.miekir.mvp.presenter;
 
 import androidx.lifecycle.MutableLiveData;
-import androidx.lifecycle.Observer;
 import androidx.lifecycle.ViewModel;
 
 import com.miekir.mvp.bean.DataResult;
-import com.miekir.mvp.constant.BaseMvpResponse;
 import com.miekir.mvp.constant.DialogAction;
+import com.miekir.mvp.jetpack.BeanLiveData;
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
@@ -25,15 +23,31 @@ public abstract class BasePresenter extends ViewModel {
      * ViewModel的生命周期和Activity保持一致;在onStart()、onResume()、onPause()时调用LiveData的setValue才会通知观察者
      * liveData在ViewModel(Presenter)创建,然后提供方法给Activity获取,方便取消观察
      */
-    private MutableLiveData<DataResult> liveData = new MutableLiveData<DataResult>();
-    private MutableLiveData<DataResult> dialogLiveData = new MutableLiveData<DataResult>();
-    public MutableLiveData<DataResult> getLiveData() {
-        return liveData;
+    private MutableLiveData<DataResult<?>> commonLiveData = new MutableLiveData<>();
+    private MutableLiveData<DataResult<?>> dialogLiveData = new MutableLiveData<>();
+    public MutableLiveData<DataResult<?>> getCommonLiveData() {
+        return commonLiveData;
     }
-    public MutableLiveData<DataResult> getDialogLiveData() {
+    public MutableLiveData<DataResult<?>> getDialogLiveData() {
         return dialogLiveData;
     }
-    private List<MutableLiveData<Object>> specificLiveDataList = new CopyOnWriteArrayList<>();
+
+    private List<BeanLiveData<?>> liveDataList = new CopyOnWriteArrayList<>();
+    public List<BeanLiveData<?>> getLiveDataList() {
+        return liveDataList;
+    }
+
+    protected <T> BeanLiveData<T> getLiveData(boolean withDialog) {
+        if (withDialog) {
+            showLoading();
+        }
+        BeanLiveData<T> liveData = new BeanLiveData<>(this, withDialog);
+        liveDataList.add(liveData);
+        return liveData;
+    }
+    protected <T> BeanLiveData<T> getLiveData() {
+        return getLiveData(false);
+    }
 
     public void showLoading() {
         showLoading("");
@@ -59,16 +73,21 @@ public abstract class BasePresenter extends ViewModel {
     public abstract void init();
 
     /**
-     * 视图被销毁时
+     * 视图被销毁时,任务被取消,界面也不存在了
      */
     public void detachView() {
-        liveData = null;
+        commonLiveData = null;
         dialogLiveData = null;
         onTaskCancel();
     }
 
     /**
-     * 当任务被取消时
+     * 当任务被取消时,界面还存在
      */
-    public abstract void onTaskCancel();
+    public void onTaskCancel() {
+        for (BeanLiveData<?> liveData : liveDataList) {
+            liveData.cancelObserve();
+        }
+        liveDataList.clear();
+    }
 }

+ 4 - 4
mvp/src/main/java/com/miekir/mvp/view/ViewHelper.java

@@ -40,8 +40,8 @@ public class ViewHelper {
                     continue;
                 }
 
-                MutableLiveData<DataResult> liveData = presenter.getLiveData();
-                MutableLiveData<DataResult> dialogData = presenter.getDialogLiveData();
+                MutableLiveData<DataResult<?>> liveData = presenter.getCommonLiveData();
+                MutableLiveData<DataResult<?>> dialogData = presenter.getDialogLiveData();
                 if (dialogData != null) {
                     dialogData.removeObservers(owner);
                 }
@@ -157,10 +157,10 @@ public class ViewHelper {
                 };
 
                 if (injectViewModel.isPersist()) {
-                    presenter.getLiveData().observeForever(observer);
+                    presenter.getCommonLiveData().observeForever(observer);
                     presenter.getDialogLiveData().observeForever(dialogObserver);
                 } else {
-                    presenter.getLiveData().observe(owner, observer);
+                    presenter.getCommonLiveData().observe(owner, observer);
                     presenter.getDialogLiveData().observe(owner, dialogObserver);
                 }
 

+ 1 - 0
mvp/src/main/java/com/miekir/mvp/widget/LVCircularRing.java

@@ -12,6 +12,7 @@ import android.util.AttributeSet;
 import android.view.View;
 import android.view.animation.LinearInterpolator;
 
+// todo 内存泄露
 public class LVCircularRing extends View {
 
     private float mWidth = 0f;