Handler内存泄漏-解决:使用静态类和弱引用
// 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内存泄漏-解决:使用静态类和弱引用相关推荐
- Handler内存泄漏问题解决方案(Android,第一行代码,This Handler class should be static or leaks might occur)
1 问题背景 博主最近在复习<第一行代码>的第10.2.2章节--在子线程中更新UI,书中给出的在UI主线程中用匿名内部类实现Handler的写法如下: private Handler h ...
- android handler 销毁,Android Handler内存泄漏原因及解决方案
目录: 1.须知: 主线程Looper生命周期和Activity的生命周期一致. 非静态内部类,或者匿名内部类.默认持有外部类引用. 2.原因: Handler造成内存泄露的原因.非静态内部类,或者匿 ...
- 【Android -- 学习笔记】Handler 内存泄漏分析及解决
一.介绍 首先,请浏览下面这段 handler 代码: public class SampleActivity extends Activity {private final Handler mLea ...
- Handler内存泄漏原因及解决方案
一.Handler造成内存泄露的原因 在Activity内将Handler声明成非静态内部类或者匿名内部类,这样Handle默认持有外部类Activity的引用.如果Activity在销毁时,Hand ...
- Handler消息机制(八):Handler内存泄漏的场景有哪些,如何避免
使用AndroidStudio检测内存泄漏: 一.内存泄漏的原因 一般内存泄漏(traditional memory leak)的原因是:由忘记释放分配的内存导致的. 逻辑内存泄漏(logical m ...
- [JAVA]第二篇(内存管理,HashMap内存泄漏解决办法)
网上看到一个关于内存泄漏处理的例子,原网址:http://www.jb51.net/article/49428.htm,下面笔者将具体分析下这篇文章中的代码,并从中学习JAVA的内存管理. (Begi ...
- dotnetty java netty,『神坑』DotNetty 内存泄漏 解决办法
背景 近来在用 DotNetty 实现一个文件上传下载的同步服务. 其中:客户端下载服务端的文件,客户端多次请求,从服务端将文件分片下载下来,追加到本地磁盘. -- 非常简单的代码,都写了几十次了,驾 ...
- iOS之深入解析内存管理散列表SideTables和弱引用表weak_table的底层原理
一.SideTables 和 weak_table 的关系 在 runtime 中,有四个数据结构非常重要,分别是 SideTables,SideTable,weak_table_t 和 weak_e ...
- Lua弱引用表处理普通的内存泄漏
Lua中有垃圾回收机制(GC)的,支持GC的对象有五种string,table,function,full userdata,thread,理论上不会有内存泄漏,但是进行GC时,如果这个对象还有引用, ...
- Android 中内存泄漏的原因和解决方案
之前研究过一段时间关于 Android 内存泄漏的知识,大致了解了导致内存泄漏的一些原因,但是没有深入去探究,很多细节也理解的不够透彻,基本上处于一种似懂非懂的状态,最近又研究了一波,发现有很多新的收 ...
最新文章
- 【Qt】信号和槽对值传递参数和引用传递参数的总结
- 腾讯云100亿元目标达成,发阳光普照奖iPhone 11 Pro,你酸了吗?
- sql mysql 删除数据库_在sql中将已建数据库删除的详细步骤
- 老婆给当程序员的老公打电话:今天下班顺路买斤元宵……
- 中文分词工具的初步使用图解
- 2014年06月30日
- ISO七层参考模型, TCP/IP
- uni-app项目实现客服、用户聊天
- 脚本程序gdb 脚本
- 亿级APP支付宝在移动端的高可用技术实践
- 使用安全浏览器将网页保存为pdf的方法步骤
- android qq 登录 qq号,手机QQ异常登录怎么办 QQ帐号无法登录解决办法
- 如何配置ASP运行环境
- saas 系统租户个性化域名租户绑定自己域名的解决方案
- Python实现人脸识别,一行代码,多种功能,易上手又好操作
- 数据库隔离级别解决脏读、不可重复读、幻读
- Chrome —— 必备插件
- 办公技巧:常用的100个Word快捷键
- 什么是照度(光照强度)?
- getAttribute 和setAttribute 的使用方法
热门文章
- numpy 矩阵对角线_python – 使用numpy将矩阵更高的对角线清零
- beta版和alpha版
- 基于设备树的TQ2440触摸屏驱动移植
- vue 之 render函数 封装 input组件
- 安全网站导航 farmsec
- var,let const,const 变量提升
- 台式电脑自带照片编辑软件将二寸照片改为一寸照片
- idea添加目录时,Mark Directory as的几个选项详解
- java读取文件(java读取文件指定内容)
- iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 3306 -j DNAT --to-destinatio