最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

Android进阶

互联网 admin 23浏览 0评论

Android进阶

最近得病了,看到代码黄色警报不是很爽。虽然不影响运行,但是看着代码不干净不利索。


Handler,线程通信,用的比较多吧,今天写代码一如往常的:

	private Handler smsHandler = new Handler(){public void handleMessage(Message msg) {};};
感觉没什么错误,怎么出黄色警报了。

This Handler class should be static or leaks might occur 

大体意思是说 Handler应该是静态的,否则会造成内存溢出。

然后将Handler用static修饰,ok,警报消失。


但是遇到问题了:不设置成静态会造成内存溢出?要毁三观?然后就开始寻求网络资源的帮助

.html

在这里找到了答案,MessageQueue中的消息队列会一直持有对handler的引用,而作为内部类的handler会一直持有外部类的引用,就会导致外部类不能被GC回收。当我们发延时很长的msg时就容易出现泄漏。所以此处应该设置为static,然后Handler就会跟随类而不是跟随类的对象加载,也就不再持有外部类的对象引用。

单单这个问题可以直接看上面这篇文章。


通过搜索还找到了另一个解决黄色警报的解决方案:在新建Handler对象的时候传入一个Handler.Callback对象。

	private Handler mHandler = new Handler(new Handler.Callback() {@Overridepublic boolean handleMessage(Message msg) {return false;}});
以前还没注意过这个参数呢,这个方法,返回值都是干啥的?

然后去看了一下这一块的源码:

    /*** Callback interface you can use when instantiating a Handler to avoid* having to implement your own subclass of Handler.** @param msg A {@link android.os.Message Message} object* @return True if no further handling is desired*/public interface Callback {<span style="white-space:pre">	</span>// callback接口public boolean handleMessage(Message msg);}/*** Subclasses must implement this to receive messages.*/public void handleMessage(Message msg) {}/*** Handle system messages here.*/public void dispatchMessage(Message msg) {if (msg.callback != null) { // callback是msg中的一个字段,是一个Runnable对象,当通过handler.post方法发送一个runnable的时候就会被封装到这个msg中handleCallback(msg); // 此方法是Handler中的一个静态方法,方法体:message.callback.run();只有这一句,可以看出是直接调用的run()方法,没有新建线程,否则也不符合这里线程通信了对吧。} else {if (mCallback != null) { // mCallback就是上面接口的对象if (mCallback.handleMessage(msg)) { // 如果返回true直接return结束方法,不再调用handler中的<span style="font-family: Arial, Helvetica, sans-serif;">handleMessage方法。</span>return;}}handleMessage(msg);// handler中的消息处理方法}}

Looper从MQ中拿到一个msg就会调用handler中的dispatchMessage方法,然后有此方法进行分发处理。想到触摸时间分发了木有?

最后记录一下Message对象的获取,原来一直使用Message.obtain方法来获取,今天无意间发现了handler.obtainMessage方法也可以获取。

通过源码发现,其实handler.obtainMessage最终也是调用了Message中的一系列obtain方法。



Android进阶

最近得病了,看到代码黄色警报不是很爽。虽然不影响运行,但是看着代码不干净不利索。


Handler,线程通信,用的比较多吧,今天写代码一如往常的:

	private Handler smsHandler = new Handler(){public void handleMessage(Message msg) {};};
感觉没什么错误,怎么出黄色警报了。

This Handler class should be static or leaks might occur 

大体意思是说 Handler应该是静态的,否则会造成内存溢出。

然后将Handler用static修饰,ok,警报消失。


但是遇到问题了:不设置成静态会造成内存溢出?要毁三观?然后就开始寻求网络资源的帮助

.html

在这里找到了答案,MessageQueue中的消息队列会一直持有对handler的引用,而作为内部类的handler会一直持有外部类的引用,就会导致外部类不能被GC回收。当我们发延时很长的msg时就容易出现泄漏。所以此处应该设置为static,然后Handler就会跟随类而不是跟随类的对象加载,也就不再持有外部类的对象引用。

单单这个问题可以直接看上面这篇文章。


通过搜索还找到了另一个解决黄色警报的解决方案:在新建Handler对象的时候传入一个Handler.Callback对象。

	private Handler mHandler = new Handler(new Handler.Callback() {@Overridepublic boolean handleMessage(Message msg) {return false;}});
以前还没注意过这个参数呢,这个方法,返回值都是干啥的?

然后去看了一下这一块的源码:

    /*** Callback interface you can use when instantiating a Handler to avoid* having to implement your own subclass of Handler.** @param msg A {@link android.os.Message Message} object* @return True if no further handling is desired*/public interface Callback {<span style="white-space:pre">	</span>// callback接口public boolean handleMessage(Message msg);}/*** Subclasses must implement this to receive messages.*/public void handleMessage(Message msg) {}/*** Handle system messages here.*/public void dispatchMessage(Message msg) {if (msg.callback != null) { // callback是msg中的一个字段,是一个Runnable对象,当通过handler.post方法发送一个runnable的时候就会被封装到这个msg中handleCallback(msg); // 此方法是Handler中的一个静态方法,方法体:message.callback.run();只有这一句,可以看出是直接调用的run()方法,没有新建线程,否则也不符合这里线程通信了对吧。} else {if (mCallback != null) { // mCallback就是上面接口的对象if (mCallback.handleMessage(msg)) { // 如果返回true直接return结束方法,不再调用handler中的<span style="font-family: Arial, Helvetica, sans-serif;">handleMessage方法。</span>return;}}handleMessage(msg);// handler中的消息处理方法}}

Looper从MQ中拿到一个msg就会调用handler中的dispatchMessage方法,然后有此方法进行分发处理。想到触摸时间分发了木有?

最后记录一下Message对象的获取,原来一直使用Message.obtain方法来获取,今天无意间发现了handler.obtainMessage方法也可以获取。

通过源码发现,其实handler.obtainMessage最终也是调用了Message中的一系列obtain方法。



与本文相关的文章

发布评论

评论列表 (0)

  1. 暂无评论