Android 开发的小伙伴都知道, 典型的开发场景就是用 Handler
来更新UI或者做一些简单耗时的操作。
举个例子,这样一写就完成了。
Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 99:
// do something
sendEmptyMessageDelayed(100, 2000);
break;
case 100:
// do something
break;
default:break;
}
}
};
mHandler.sendEmptyMessage(99);
然而,AS 一这样写,立马报黄,提示如下
This Handler class should be static or leaks might occur (anonymous android.os.Handler)
写个 Handler 就提示会内存泄漏了,还让不让人好好写 bug 了。
有个问题,假如写了个 for 循环,发送一万次消息,会不会有问题?
写个 demo 验一下就知道不会有问题。
关于 Handler 的内存泄漏,摘抄一段解释说明。
mHandler 会作为成员变量保存在发送的消息msg 中,即 msg 持有mHandler 的引用,而 mHandler 是 Activity 的非静态内部类实例,即mHandler 持有 Activity 的引用,那么我们就可以理解为 msg 间接持有 Activity 的引用。msg 被发送后先放到消息队列 MessageQueue 中,然后等待 Looper 的轮询处理(MessageQueue 和 Looper 都是与线程相关联的, MessageQueue 是 Looper 引用的成员变量,而 Looper 是保存在ThreadLocal 中的)。那么当 Activity 退出后,msg 可能仍然存在于消息对列MessageQueue 中未处理或者正在处理,那么这样就会导致 Activity 无法被回收,以致发生Activity 的内存泄露。
通常在Android 开发中如果要使用内部类,但又要规避内存泄露,一般都会采用 静态内部类 + 弱引用
的方式。
优化一下 Handler ,优化示例,
用静态内部类的方式自定义一个 Handler ,使用 WeakReference
实现弱引用。
传入的 SecondActivity 是使用这个 Handler 的 Activity ,按照实际情况传入即可; 传入Fragment 也是可以的。
private static class SecondHandler extends Handler{
private WeakReference<SecondActivity> mWeakReference;
public SecondHandler(SecondActivity secondActivity) {
mWeakReference = new WeakReference<>(secondActivity);
}
@Override
public void handleMessage(Message msg) {
SecondActivity host = mWeakReference.get(); // 判断所在的 Activity 的引用是否被回收了
if (host != null) {
switch (msg.what){
case 99:
// do something
sendEmptyMessageDelayed(100, 2000);
break;
case 100:
// do something
break;
default:break;
}
}
}
}
摘抄一段解释说明:
mHandler 通过弱引用的方式持有Activity,当GC 执行垃圾回收时,遇到Activity 就会回收并释放所占据的内存单元。这样就不会发生内存泄露了。
参考构造函数,初始化也很简单,使用的话还是 Handler 的用法。
SecondHandler mHandler = new SecondHandler(SecondActivity.this);
mHandler.sendEmptyMessage(99);
当 Activity 退出后,将 mHandler 的回调和消息移除。在 onStop 或者 onDestroy 中执行即可。
@Override
protected void onStop() {
super.onStop();
mHandler.removeCallbacksAndMessages(null);
}
传入 null 是移除所有回调和消息,查看 Handler 源码可知,
/**
* Remove any pending posts of callbacks and sent messages whose
* <var>obj</var> is <var>token</var>. If <var>token</var> is null,
* all callbacks and messages will be removed.
* */
public final void removeCallbacksAndMessages(Object token) {
mQueue.removeCallbacksAndMessages(this, token);
}
这样, Handler 的优化就完成了。
Thread 和 AsyncTask 也可以这样优化。
一、代理服务器的配置与应用随着Internet的迅速发展,宽带网络接入量快速增多,Internet终端用户数迅速膨胀,网络管理员面临的问题越来越多,问题也越来越严重,如IP资源匮乏、用户访问计费、内部网络安全等一系列问题。面临如此多的问题,我们迫切需要一个行之有效的方案应对,这个方案就是我们本章要重点学习的代理服务器。本章将介绍代理服务器的基本概念、工作原理、配置和使用方法等..._配置文件中 squid 服务默认是拒绝所有:
最近一个折腾死人的项目,用labview做二维码识别,照理来说很简单,直接调用labview 的 DM识别模块就可以,由于识别的二维码各种各样,出现各种各样的问题,记录一下。逻辑,先飞拍,初始设置好阈值,二维码大小,比例,border占比,其他的都auto,然后识别不到的,加阈值减阈值再算一次,加ROI不加ROI再算一次;都拍不出来,相机回去重拍一次,左移右移再拍一次,调算法。问题,对于灰底黑码的,产品表面有毛刺和不平的地方,导致打光不均,散点多,识别率低,而且由于掉了多次算法,莫名其妙非常_labview二维码识别效率优化
/* 建议B站搜视频 w[i]:表示第i个物品的重量B[k - 1] [c - w[ i ] ] :表示只考虑前(k-1)个物品,在c-w[i]的承重下所能获得的最大价值.此时说明背包减去了C[j]的重量,所以后面要加v[i],获得了第i个物品的价值. 可以理解为从上一个状态一直留着空间给第i个物品.看看加上第i个物品的价值能不能超过不花费w[i]的容量,花不起就还是和k-1个物品的最..._一句话解释背包问题
产生原因:所使用的网络供应商,有些会设置一些透明缓存,以增加网络内部速度,减少出口的流量,所获取的某些文件不是源服务器上的真正文件,是从缓存中获取的,当缓存中获取的一些校验信息跟源中不一致的时候,自然提示校验失败,无法继续更新。解决办法:1)删掉/var/lib/apt/lists 这个目录下的东西sudo rm -fR /var/lib/apt/lists/*2)新建相应文件夹...
--创建作业,自动清理tempdb数据库日志 --创建作业 exec msdb..sp_add_job @job_name=tempdb日志清理 --创建作业步骤 declare @sql varchar(800),@dbname varchar(250) select @sql=DUMP TRANSAC_数据库tempdb的日志已满怎么解决
重载赋值操作符重载赋值操作符重载赋值操作符赋值操作符“=”可以用来将一个对象拷贝给另一个已经存在的对象。如果我们重新定义了一种新的数据类型,比如说复数类,那么我们就需要重载一下赋值操作符,使之能够满足我们的赋值需求。当然,拷贝构造函数也有同样的功能。拷贝构造函数可以将一个对象拷贝给另一个新建的对象。如果我们没有在类中显式定义拷贝构造函数,也没有重载赋值操作符,那么系统会为我们的类提供一个默认的拷贝构造函数和一个赋值操作符。前面在介绍类的相关知识时已经提到,系统为我们提供的默认拷贝构造函数只是将源对象中_c++ 重写赋值运算
<script> /* ****** 元素视图属性 * offsetWidth 水平方向 width + 左右padding + 左右border-width * offsetHeight 垂直方向 height + 上下padding + 上下border-width * * clientWidth 水平方向 width + 左右padding * clientHeight 垂直方向 height + 上下padding
在正式开始学习 Python 这门高级编程语言之前,我们有必要先讨论一下“Python 是什么”。一、Python 是什么1.1.Python 名字来历Python 英文原意为“蟒蛇”,直到 1989 年荷兰人 Guido van Rossum (简称 Guido)发明了一种面向对象的解释型编程语言,并将其命名为 Python,才赋予了它表示一门编程语言的含义。Python的诞..._python 经常被用于 web 开发,尽管目前 php、
ASIHTTPRequest-详解ASIHTTPRequest 是一款极其强劲的 HTTP 访问开源项目。让简单的 API 完成复杂的功能,如:异步请求,队列请求,GZIP 压缩,缓存,断点续传,进度跟踪,上传文件,HTTP 认证。在新的版本中,还加入了 Objective-C 闭包 Block 的支持,让我们的代码加轻简灵活。 下面就举例说明它的 API 用法。_asihttprequest 回调线程
子类与父类: 多个类中具有相同的属性和行为时,将这些内容拿出来单独放到一个类中,其他多个类无需再定义这些属性和行为,只需要 继承这个类即可。单独的这个类称为父类,基类或超类。多个类被称为子类或者派生类。继承以后,可以在父类的基础上加 入自己的新成员。继承: 格式:class 子类名 extends 父类名 {} 好..._class father{ //基类public: father(string s):name(s) { }private: string
sessionStorage不能跨标签页解决方案–vue项目现有的浏览器存储机制localStorage :~5MB,数据永久保存直到用户手动删除sessionStorage :~5MB,数据只在当前标签页有效cookie :~4KB,可以设置成永久有效session cookie :~4KB,当用户关闭浏览器时删除(并非总能立即删除)安全的认证token保存一些重要的系统会要求当用户关闭标签页时会话立刻到期。为了达到这个目的,不仅绝对不应该使用cookies来保存任何敏感信息(例如认证to_sessionstorage跨页面
远程仓库请参考:https://github.com/MrZhousf/AARaar引用很简单,将sdk-zhousf-1.0-20170907.054540-1.aar复制到libs包下,在项目的build.gradle文件中增加以下代码即可:compile(name:'sdk-zhousf-1.0-20170907.054540-1',ext:'aar')但是如果aar中包含了远..._com.zhousf.lib:okhttp3:2.9.8