2019-06-26 关于自定义接口回调 内存泄漏

2019-06-26  本文已影响0人  馒Care

自定义接口回调操作不当容易导致内存泄漏

public interface LoginInterface{
      void onLoginSuccess();
      void onLoginFailed();
}

如上的使用,是我们日常开发最常见的使用方式了。我们猜想下,如果我们使用了网络请求,这个操作还没有执行完毕的时候,回调里面的匿名内部类已经隐式的持有了外部类的引用,这就导致了内存无法被回收,为什么无法被回收呢?可以参考下JVM垃圾回收机制里面的标记回收法,这里不做详细记录。来看看有可能导致泄漏的伪代码吧。

LoginInterface loginInterface = new LoginInterface ();

public void login(User user){
      RetrofitClient.getInstance().login(user).subscriber(
            new  Consumer(<BaseResponse> response){
              loginInterface.onLoginSuccess();
        },new Consumer(<Exception> ex){
              loginInterface.onLoginFailed();
        }
}

通过以上伪代码,我们可以看到,登录是个耗时操作,这个时候,如果是弱网络情况下,我们强制退出当前页面,那么onLoginSuccess 和 onLoginFailed 由于会持有Activity的外部类引用,导致JVM无法回收,造成了内存泄漏。所以,需要这么解决

protected Reference<LoginInterface > weakLoginInterface;
//View接口类型弱引用
public void login(User user,LoginInterface  loginInterface){
weakLoginInterface= new  Reference<LoginInterface >(loginInterface);
      RetrofitClient.getInstance().login(user).subscriber(
            new  Consumer(<BaseResponse> response){
              if(weakLoginInterface.get()==null)return;
              weakLoginInterface.get().onLoginSuccess();
        },new Consumer(<Exception> ex){
              if(weakLoginInterface.get()==null)return;
              weakLoginInterface.get().onLoginFailed();
        }
}

添加弱引用,来避免当Activity被销毁的时候,内存无法回收的情况,弱引用为啥可以解决,这里不做解释,仅给出方案。在Activity OnDestory的时候,调用

 public void detachView() {//解除关联
        if (weakLoginInterface!= null) {
            weakLoginInterface.clear();
            weakLoginInterface= null;
        }
    }

以上方案也适用于MVP的常规内存泄漏解决方案,接收的
protected Reference<T> weakInterface;使用泛型来接受,定义在BasePresenter,在Activity的OnDestory方法调用P层内部方法detachView(),解除关联,并把P置null(如果有需要)

上一篇 下一篇

猜你喜欢

热点阅读