美文网首页
2019-06-26 关于自定义接口回调 内存泄漏

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

作者: 馒Care | 来源:发表于2019-06-26 23:13 被阅读0次

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

    • 列表第一项面试中,经常被问到MVP是否会导致内存泄漏,相信很多人都说会导致,但是如何解决,大部分人都是回答说,使用lifecycle,让第三方来托管泄漏问题,但是真正使用中,如果没有理解泄漏的原理还是不够的。
    • 撇开MVP来说,我们日常也经常喜欢使用自定义的interface来操作一系列的接口回调,这样可以一定程度上降低我们的耦合,但是不管是使用MVP或者自定义interface都是会由于在子线程操作耗时动作导致泄漏。举个栗子吧
    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(如果有需要)

    相关文章

      网友评论

          本文标题:2019-06-26 关于自定义接口回调 内存泄漏

          本文链接:https://www.haomeiwen.com/subject/sahkcctx.html