使用ViewModel+Data Binding解决内存泄漏问题

1.在我们写APP的时候经常会遇到这种情况,点击一个按钮后,通过网络异步操作从后台获取信息,然后再展示到UI,例如

public class MyActivity extends BaseActivity {
    private void getUser(){
        LoadingDialog loadingDialog=new LoadingDialog(this,"加载中");
        loadingDialog.show();
        Request request = new Request.Builder()
                .url("getuser.php")
                .build();
        Call call =HttpUtils.getInstance().newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //更新UI
            }
        });
    }
}

2.由于子线程中不能直接操作UI,所以我们这个时候我们需要利用Handler或者其他方式在主线程中进行

    private static <T> Callback getCallBack() {
        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                //更新UI
            }
        };
        return new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Message message = handler.obtainMessage(1, response);
                handler.sendMessage(message);
            }
        };

    }

3.Handler在创建的时候会自动持有Activity对象,所以在Activity被系统回收时,会没办法释放导致内存泄漏,如果去网上搜索,大多数都是让你使用弱引用或者静态内部类来解决,但是这两种方式都很麻烦而且使代码变的很难看,目前为止我绝得最好的方式是使用ViewModel+Data Binding

4.ViewModel有以下好处

  • ViewModel不会持有Activity对象
  • ViewModel会监视Activity的生命周期,在Activity的生命周期里可能触发多次OnCreate,但是ViewModel只会创建一次
  • ViewModel可以自动帮你保存数据,让Activity销毁再创建后可以恢复数据

5.ViewModel代码如下,网络请求开始时会设置Result为0,结束时会设置Result为1,这里我只是打个比方,你也可以使用ObservableField或者BaseObservable传递更复杂的数据,UserInfoViewModel也可以继承AndroidViewModel,它是一个拥有上下文的ViewModel

public class UserInfoViewModel extends ViewModel {

    private final ObservableInt mResult=new ObservableInt();

    public ObservableInt getResult() {
        return mResult;
    }

    public void getUser(){
        Request request = new Request.Builder()
                .url("getuser.php")
                .build();
        Call call =HttpUtils.getInstance().newCall(request);
         mResult.set(0);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                mResult.set(1);
            }
        });
    }
}

6.下面是Activity里的代码,Activity可以监视Result来更新UI

    private void subscribeUi() {
        mUserInfoViewModel.getResult().addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
            @Override
            public void onPropertyChanged(Observable sender, int propertyId) {
                int result=mUserInfoViewModel.getResult().get();
                switch (result){
                    case 0:
                        mLoadingDialog.show("加载中");
                        break;
                    case 1:
                        mLoadingDialog.dismiss();
                        ToastUtils.show("获取数据成功");
                        break;
                   default:

                        break;
                }
            }
        });
    }

原文地址:https://www.cnblogs.com/Potato-Eater/p/9584524.html

时间: 2024-09-30 12:42:00

使用ViewModel+Data Binding解决内存泄漏问题的相关文章

使用Xcode Instruments Leak解决内存泄漏问题

iOS 5.0之后apple引入了Xcode编译器特性ARC(Automatic Reference Counting,自动引用计数)来帮助开发者管理内存,但为了追求app的高性能与减少安装包大小,工作中很多时候需要我们手动管理内存.再牛的开发者也不能保证自己写的code 100%没有内存泄露,出现内存泄露不可怕,可怕的是我们时间与精力花了大把,但内存泄露依旧没解决,即影响了工作效率也影响自己的心情. 下面就讲解xcode中的内存调试神器---Instruments Leak ,不管是ios开发

捉虫记录:解决内存泄漏问题

LinJM   2014_05_23 解决内存泄漏问题 在VS2010的Debug模式下面,点击运行,然后退出,之后会在输出框里面出现内存泄漏信息(如下图所示). Analysis:主要是new了之后没有delete相应的变量,所以,很明显就是要在不使用时delete掉这个变量.不过,有个问题,如下图所示: 我代码修改位置如下所示: 我把红下划线部分注释掉就不会出现上面那个问题,后来讨论分析才发现pBim现在分配给了pAdjustmentLyInfo,二者现在指向同一个内存空间,当我delete

ES6通过WeakMap解决内存泄漏问题

一.Map 1.定义 Map对象保存键值对,类似于数据结构字典:与传统上的对象只能用字符串当键不同,Map对象可以使用任意值当键. 2.语法 new Map([iterable]) 属性 size:返回键值对的数量. 操作方法 set(key, value):设置(新增/更新)键key的值为value,返回Map对象. get(key):读取键key的值,没有则返回undefined. has(key):判断一个Map对象中是否存在某个键值对,返回true/false. delete(key):

Android 如何有效的解决内存泄漏的问题

https://www.cnblogs.com/zhaoyanjun/p/5981386.html 前言:最近在研究Handler的知识,其中涉及到一个问题,如何避免Handler带来的内存溢出问题.在网上找了很多资料,有很多都是互相抄的,没有实际的作用. 本文的内存泄漏检测工具是:LeakCanary  github地址:https://github.com/square/leakcanary 什么是内存泄漏? 内存泄漏是当程序不再使用到的内存时,释放内存失败而产生了无用的内存消耗.内存泄漏并

解决内存泄漏更加清楚的认识到Java匿名类与外部类的关系

1.事件起因 在做项目的时候,通过Android Studio的Memory Monitor窗口观察程序内存使用情况,发现当程序退出的时候,有一部分应该释放掉的内存没有释放掉,知道程序中应该有内存泄漏了.为了发现程序中的内存泄漏,我切换了IDE工具到Eclipse,里面安装了内存泄漏的分析工具MAT,具体怎么用MAT分析内存泄漏可以自己Google,我把我自己找到内存泄漏的地方贴出来 从上图中可以看到,有24M左右的内存被mView(其实它真正是一个Fragment)这个变量持有,导致Java垃

使用 Android Studio 检测内存泄漏与解决内存泄漏问题

自从Google在2013年发布了Android Studio后,Android Studio凭借着自己良好的内存优化,酷炫的UI主题,强大的自动补全提示以及Gradle的编译支持正逐步取代Eclipse,成为主流的Android开发IDE.Android Studio在为我们提供了良好的编码体验的同时,也提供了许多对App性能分析的工具,让开发者可以更方便分析App性能.Google在IO大会上一直告诫开发者不要无节制的使用手机内存,要注意一些不良的开发习惯会导致App的内存泄漏.虽然如今网上

Android内存泄漏查找和解决

Android内存泄漏查找和解决 目录: 内存泄漏的概念 一个内存泄漏的例子 Java中"失效"的private修饰符 回头看内存泄漏例子泄漏的重点 强引用与弱引用 解决内部类的内存泄漏 Context造成的泄漏 使用LeakCanary工具查找内存泄漏 总结 一.内存泄漏概念 1.什么是内存泄漏? 用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元.直到程序结束.即所谓的内存泄漏. 其实说白了就是该内存空间使用完毕之后未回收 2.内存泄漏会导致的问题 内

android 内存泄漏分析技巧

java虚拟机运行一般都有一个内存界限,超过这个界限,就会报outofmemory.这个时候一般都是存在内存泄漏.解决内存泄漏问题,窃以为分为两个步骤:分析应用程序是否真的有内存泄漏,找到内存泄漏的地方.这两个步骤都不是一般意义上的调试,直接打log,断点调试都不是太给力.动脑筋想一想,内存问题应该在很多地方上都会出现,这么常见的问题应该是有工具的.android现在更可以说是一个生态系统,当然也有很多开发辅助工具.在前面的两个步骤中都有很强大的武器,熟练的掌握这些利器,分析问题就会事半功倍.

&lt;转&gt;Python的内存泄漏及gc模块的使用分析

一般来说在 Python 中,为了解决内存泄漏问题,采用了对象引用计数,并基于引用计数实现自动垃圾回收.由于Python 有了自动垃圾回收功能,就造成了不少初学者误认为自己从此过上了好日子,不必再受内存泄漏的骚扰了.但如果仔细查看一下Python文档对 __del__() 函数的描述,就知道这种好日子里也是有阴云的.下面摘抄一点文档内容如下: Some common situations that may prevent the reference count of an object from