//    private Handler mHandler=new Handler(){//导os包
//        @Override
//        public void handleMessage(Message msg) {
//            super.handleMessage(msg);
//            switch (msg.what){
//                case 1:
//
//                    break;
//
//                case 2:
//
//                    break;
//
//            }
//        }
//    };

Activity这样使用Handler会存在内存泄漏的问题
解决:
1Handler使用静态内部类创建 2对所持有的Activity引用变为弱引用
原因:
1在Java 中,非静态的内部类和匿名内部类都会隐式地持有其外部类的引用,静态的内部类不会持有外部类的引用。
2由于Handler不再持有外部类对象的引用,导致程序不允许你在Handler中操作Activity中的对象了。所以你需要在Handler中增加一个对Activity的弱引用(WeakReference)。

//创建静态内部类
private static class MyHandler extends Handler {//持有弱引用MainActivity,GC回收时会被回收掉.WeakReference<OkhttpTestActivity> mWeakReference;private MyHandler(OkhttpTestActivity mainActivity) {mWeakReference = new WeakReference<>(mainActivity);}@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what){case 1:if(mWeakReference.get()!=null){mWeakReference.get().mTv.setText(msg.getData().getString("response"));}else {Log.e("wy","Activity销毁,弱引用也随之销毁");}break;case 2:break;}}}
Handler handler = new MyHandler(this);

子线程中发送消息

Bundle mBundle= new Bundle();
mBundle.putString("response",response.toString());
Message msg=Message.obtain();
msg.what=1;
msg.setData(mBundle);
handler.sendMessage(msg);

使用okhttp异步请求进行网络访问,全代码

implementation("com.squareup.okhttp3:okhttp:4.8.1")
package com.wintec.netframworktest;import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;import java.io.IOException;
import java.lang.ref.WeakReference;import androidx.appcompat.app.AppCompatActivity;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;public class OkhttpTestActivity extends AppCompatActivity {OkHttpClient client;private  TextView mTv;//创建静态内部类private static class MyHandler extends Handler {//持有弱引用MainActivity,GC回收时会被回收掉.WeakReference<OkhttpTestActivity> mWeakReference;private MyHandler(OkhttpTestActivity mainActivity) {mWeakReference = new WeakReference<>(mainActivity);}@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what){case 1:if(mWeakReference.get()!=null){mWeakReference.get().mTv.setText(msg.getData().getString("response"));}else {Log.e("wy","Activity销毁,弱引用也随之销毁");}break;case 2:break;}}}Handler handler = new MyHandler(this);//@SuppressLint("HandlerLeak")
//    private Handler mHandler=new Handler(){//导os包
//        @Override
//        public void handleMessage(Message msg) {
//            super.handleMessage(msg);
//            switch (msg.what){
//                case 1:
//
//                    break;
//
//                case 2:
//
//                    break;
//
//            }
//        }
//    };@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mTv = (TextView) findViewById(R.id.tv);Request request = new Request.Builder().url("https://wap.peopleapp.com/article/5933922/5852020").build();client = new OkHttpClient();
//         OkHttp的同步请求会阻塞当前线程,因此不能在UI线程中请求,需要开启子线程,在子线程中发送请求。//         new Thread(new Runnable() {
//             @Override
//             public void run() {
//                 try {
//                     Log.e("wy","okhttp同步请求返回: "+ client.newCall(request).execute().toString());
//                     mTv.setText(client.newCall(request).execute().toString());
//                 } catch (IOException mE) {
//                     mE.printStackTrace();
//                 }
//             }
//         }).start();//         异步请求Call call=client.newCall(request);call.enqueue(new Callback() {@Overridepublic void onResponse(Call call, Response response) throws IOException {Log.e("wy","okhttp异步请求response返回:"+response.toString());
//                android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
//                mTv.setText(response.toString());
//                使用Handler进行线程通讯Bundle mBundle= new Bundle();mBundle.putString("response",response.toString());Message msg=Message.obtain();msg.what=1;msg.setData(mBundle);handler.sendMessage(msg);//                OkhttpTestActivity.this.runOnUiThread(new Runnable() {
//                    public void run() {
//                        mTv.setText(response.toString());
//                    }
//                });}@Overridepublic void onFailure(Call call, IOException e) {Log.e("wy","okhttp异步请求异常:"+e);}});}@Overrideprotected void onDestroy() {super.onDestroy();handler.removeCallbacksAndMessages(null);}
}

在我们以后开发中使用handler时,就可以使用静态类和弱引用,这样可以避免内存泄漏现象,达到内存优化的目的。

Handler内存泄漏-解决:使用静态类和弱引用相关推荐

  1. Handler内存泄漏问题解决方案(Android,第一行代码,This Handler class should be static or leaks might occur)

    1 问题背景 博主最近在复习<第一行代码>的第10.2.2章节--在子线程中更新UI,书中给出的在UI主线程中用匿名内部类实现Handler的写法如下: private Handler h ...

  2. android handler 销毁,Android Handler内存泄漏原因及解决方案

    目录: 1.须知: 主线程Looper生命周期和Activity的生命周期一致. 非静态内部类,或者匿名内部类.默认持有外部类引用. 2.原因: Handler造成内存泄露的原因.非静态内部类,或者匿 ...

  3. 【Android -- 学习笔记】Handler 内存泄漏分析及解决

    一.介绍 首先,请浏览下面这段 handler 代码: public class SampleActivity extends Activity {private final Handler mLea ...

  4. Handler内存泄漏原因及解决方案

    一.Handler造成内存泄露的原因 在Activity内将Handler声明成非静态内部类或者匿名内部类,这样Handle默认持有外部类Activity的引用.如果Activity在销毁时,Hand ...

  5. Handler消息机制(八):Handler内存泄漏的场景有哪些,如何避免

    使用AndroidStudio检测内存泄漏: 一.内存泄漏的原因 一般内存泄漏(traditional memory leak)的原因是:由忘记释放分配的内存导致的. 逻辑内存泄漏(logical m ...

  6. [JAVA]第二篇(内存管理,HashMap内存泄漏解决办法)

    网上看到一个关于内存泄漏处理的例子,原网址:http://www.jb51.net/article/49428.htm,下面笔者将具体分析下这篇文章中的代码,并从中学习JAVA的内存管理. (Begi ...

  7. dotnetty java netty,『神坑』DotNetty 内存泄漏 解决办法

    背景 近来在用 DotNetty 实现一个文件上传下载的同步服务. 其中:客户端下载服务端的文件,客户端多次请求,从服务端将文件分片下载下来,追加到本地磁盘. -- 非常简单的代码,都写了几十次了,驾 ...

  8. iOS之深入解析内存管理散列表SideTables和弱引用表weak_table的底层原理

    一.SideTables 和 weak_table 的关系 在 runtime 中,有四个数据结构非常重要,分别是 SideTables,SideTable,weak_table_t 和 weak_e ...

  9. Lua弱引用表处理普通的内存泄漏

    Lua中有垃圾回收机制(GC)的,支持GC的对象有五种string,table,function,full userdata,thread,理论上不会有内存泄漏,但是进行GC时,如果这个对象还有引用, ...

  10. Android 中内存泄漏的原因和解决方案

    之前研究过一段时间关于 Android 内存泄漏的知识,大致了解了导致内存泄漏的一些原因,但是没有深入去探究,很多细节也理解的不够透彻,基本上处于一种似懂非懂的状态,最近又研究了一波,发现有很多新的收 ...

最新文章

  1. 【Qt】信号和槽对值传递参数和引用传递参数的总结
  2. 腾讯云100亿元目标达成,发阳光普照奖iPhone 11 Pro,你酸了吗?
  3. sql mysql 删除数据库_在sql中将已建数据库删除的详细步骤
  4. 老婆给当程序员的老公打电话:今天下班顺路买斤元宵……
  5. 中文分词工具的初步使用图解
  6. 2014年06月30日
  7. ISO七层参考模型, TCP/IP
  8. uni-app项目实现客服、用户聊天
  9. 脚本程序gdb 脚本
  10. 亿级APP支付宝在移动端的高可用技术实践
  11. 使用安全浏览器将网页保存为pdf的方法步骤
  12. android qq 登录 qq号,手机QQ异常登录怎么办 QQ帐号无法登录解决办法
  13. 如何配置ASP运行环境
  14. saas 系统租户个性化域名租户绑定自己域名的解决方案
  15. Python实现人脸识别,一行代码,多种功能,易上手又好操作
  16. 数据库隔离级别解决脏读、不可重复读、幻读
  17. Chrome —— 必备插件
  18. 办公技巧:常用的100个Word快捷键
  19. 什么是照度(光照强度)?
  20. getAttribute 和setAttribute 的使用方法

热门文章

  1. numpy 矩阵对角线_python – 使用numpy将矩阵更高的对角线清零
  2. beta版和alpha版
  3. 基于设备树的TQ2440触摸屏驱动移植
  4. vue 之 render函数 封装 input组件
  5. 安全网站导航 farmsec
  6. var,let const,const 变量提升
  7. 台式电脑自带照片编辑软件将二寸照片改为一寸照片
  8. idea添加目录时,Mark Directory as的几个选项详解
  9. java读取文件(java读取文件指定内容)
  10. iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 3306 -j DNAT --to-destinatio