Android Handler之使用小结

简介: 在android开发中,使用Handler处理各种消息机制。 Handler用于处理和从队列MessageQueue中得到Message。一般我们要重写Handler的handleMessage(Message msg){}方法来处理,如下代码: 使用内部类的方式实现,官方是不建议这样写的。

在android开发中,使用Handler处理各种消息机制。

Handler用于处理和从队列MessageQueue中得到Message。一般我们要重写Handler的handleMessage(Message msg){}方法来处理,如下代码:

使用内部类的方式实现,官方是不建议这样写的。

public class MainActivity extends Activity {
    
	Handler mHandler = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case 1:
				//处理各种接受消息逻辑
				break;

			default:
				break;
			}
		};
	};
}

  

这个时候Handler会被Android SDK中Lint工具检查警告你(左边那个黄色灯泡+叹号):This Handler class should be static or leaks might occur 。

 

为什么静态内部类可以解决这个问题呢?或者说静态内部类和非静态内部类的区别是什么?

举例:class A{

           int a;

           static int b

           class B{}

           static class C{}

}

 (A是外部类,B非静态内部类,C静态内部类,a普通字段,b静态字段)

1)B非静态内部类:

可以访问A.a和A.b,也就是外部的属性都能方位。因为B隐式的持有A类对象的引用,相当于A的属性

2)C静态内部类:

C只可以访问A.b,不可以方位A.a。为什么?因为C不含有A的引用,它和A类是同一个级别,只不过写到了A类的内部。

link的警告原因:

Handler匿名内部类,隐式的持有了外部类Activity的引用。

 

Message message = normalHandler.obtainMessage();
normalHandler.sendMessageAtTime(message , 100*1000);


得到的message中又含有这个Handler的引用(可以看源码)。

 

在100秒后message被执行,这期间message被放在MessageQueue中,MessageQueue在Looper中,Looper是线程的本地变量。

也就是说MainActivity即使生命周期走完了也不会垃圾回收,为什么?因为Java的垃圾回收机制,就是看一个对象有没有被引用(从线程中的主要对象开始,对象之间的引用形成网状结构,如果有类的对象不在这张网上,就证明它没被引用。这就是数据结构中图的遍历,什么连通子图,非连通子图)。而本文中一个MainActivity被Handler持有引用,Handler被Message持有引用,Message被MessageQueue持有引用,MessageQueue被Looper持有引用,Looper为线程本地变量,线程不被摧毁,它就不会被销毁。

所以即便用户已经切换、退出到别的Activity,MainActivity占有的内存仍旧不会被释放。

 

解决方案:

打破引用链?

1.Message在100秒后被处理,之后回收Message,然后回收MainActivity。(所以是实际上,你只要不发很长时间的Message也不会有什么问题)

2.使Handler不持有MainActivity的引用,用弱引用WeakReference:(简单讲,就是只有WeakReference引用的对象,垃圾回收将回收该对象)

MyHandler handler = new MyHandler(this);

	public static class MyHandler extends Handler {
		private WeakReference<MainActivity> reference;

		public MyHandler(MainActivity activity) {
			reference = new WeakReference<MainActivity>(activity);
		}

		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case 1:
				//处理接受消息逻辑
				break;

			default:
				break;
			}
		}
	}

  

为何Android界面更新,Handler作为匿名内部类来实现handlerMessage方法 

最重要的不是线程安全问题,而是android组件的监听方法中只能访问final 的属性,所以是无法修改的,只能把它交给handler处理。不能在非UI线程,绘制渲染洁面。

为何需要Handler而不用Thread。除了消息模型是UI框架的经典模式外,还涉及到UI组件不允许跨线程访问的限制。无论是.NET也好,swing也好,android也好,不允许在非UI线程中操作这一点都一样。
Handler便是android框架中异步线程代码到达同步线程的官方通道。从另一个角度说,这种基于消息模型的通信模式有时也很有用。相关的例子有IntentService,HandlerThread等。

 

 

转自:http://www.bkjia.com/Androidjc/904357.html

 

目录
相关文章
|
6月前
|
消息中间件 网络协议 Java
Android 开发中实现数据传递:广播和Handler
Android 开发中实现数据传递:广播和Handler
68 1
|
6月前
|
安全 Android开发 开发者
【Android开发小技巧】扔掉这坑人的 Handler
【Android开发小技巧】扔掉这坑人的 Handler
75 0
|
1月前
|
消息中间件 存储 Java
Android消息处理机制(Handler+Looper+Message+MessageQueue)
Android消息处理机制(Handler+Looper+Message+MessageQueue)
41 2
|
28天前
|
消息中间件 存储 Java
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
|
1月前
|
消息中间件 存储 Java
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
48 1
|
1月前
|
消息中间件 存储 Java
Android消息处理机制(Handler+Looper+Message+MessageQueue)
Android消息处理机制(Handler+Looper+Message+MessageQueue)
45 2
|
3月前
|
消息中间件 存储 Java
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
Android 消息处理机制估计都被写烂了,但是依然还是要写一下,因为Android应用程序是通过消息来驱动的,Android某种意义上也可以说成是一个以消息驱动的系统,UI、事件、生命周期都和消息处理机制息息相关,并且消息处理机制在整个Android知识体系中也是尤其重要,在太多的源码分析的文章讲得比较繁琐,很多人对整个消息处理机制依然是懵懵懂懂,这篇文章通过一些问答的模式结合Android主线程(UI线程)的工作原理来讲解,源码注释很全,还有结合流程图,如果你对Android 消息处理机制还不是很理解,我相信只要你静下心来耐心的看,肯定会有不少的收获的。
204 3
Android面试高频知识点(2) 详解Android消息处理机制(Handler)
|
4月前
|
消息中间件 调度 Android开发
Android经典面试题之View的post方法和Handler的post方法有什么区别?
本文对比了Android开发中`View.post`与`Handler.post`的使用。`View.post`将任务加入视图关联的消息队列,在视图布局后执行,适合视图操作。`Handler.post`更通用,可调度至特定Handler的线程,不仅限于视图任务。选择方法取决于具体需求和上下文。
55 0
|
5月前
|
Android开发
38. 【Android教程】Handler 消息传递机制
38. 【Android教程】Handler 消息传递机制
55 2
|
6月前
|
消息中间件 安全 数据处理
Android之Handler、Message、MessageQueue、Looper详解2
Android之Handler、Message、MessageQueue、Looper详解
81 0