线程间通信之Handler小实验
来源:互联网 发布:iphone序列号查询软件 编辑:程序博客网 时间:2024/04/27 19:02
线程间通信之Handler小实验
转载请标明地址,谢谢:http://blog.csdn.net/pfugwtg/article/details/50347341
目录
- 线程间通信之Handler小实验
- 目录
- 前言
- 基本知识
- 第一段代码
- 1这一部分代码运行后DDMS如图
- 2退出应用后再次进入应用后DDMS变成这样
- 3点击destroy按钮后的DDMS
- 小结1
- 第二段代码
- 1程序启动后日志是空的
- 2点击Send按钮后的Logcat
- 小结2
- 结尾
前言
由于项目需要,今天找了一些关于线程间通信的知识看了一下,然后自己实验总结了一下,以此备忘。
其它线程向UI线程传递消息之类的我就不写了,这类知识网上可以找一大堆,我这里主要是讲一下UI线程以外的线程间通讯。
基本知识
在非UI线程中若要创建Handler,则必需调用Looper.prepare()和Looper.loop(),但对于它们的具体调用时机,童鞋们又知道多少呢,嘿嘿嘿…
好了,肉戏来了。。。
第一段代码
package com.example.androidtest.thread.communicate;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.util.Log;public class ThreadsCommunicate { private static final String TAG = "ThreadsCommunicate"; private Thread aThread = null; private Handler mHandler = null; public ThreadsCommunicate() { aThread = new AThread(); aThread.start(); } public void sendMsg() { if(null != mHandler) { Log.d(TAG, "sendMsg success!"); mHandler.obtainMessage().sendToTarget(); } else { Log.e(TAG, "sendMsg failed..."); } } public void destroy() { if(null != mHandler) { mHandler.getLooper().quit(); } } private class AThread extends Thread { @Override public void run() { this.setName("myAThread"); Looper.prepare(); Log.i(TAG, "AThread run()"); mHandler = new Handler() { @Override public void handleMessage(Message msg) { Log.i(TAG, "Thread name:" + this.getLooper().getThread().getName()); super.handleMessage(msg); } }; Looper.loop(); super.run(); } }}
调用部分代码:
package com.example.androidtest;import com.example.androidtest.thread.communicate.ThreadsCommunicate;import android.app.Activity;import android.os.Bundle;import android.view.View;public class MainActivity extends Activity{ private ThreadsCommunicate mThreadsCommunicate; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mThreadsCommunicate = new ThreadsCommunicate(); } public void viewOnClick(View view) { switch (view.getId()) { case R.id.btn_send: mThreadsCommunicate.sendMsg(); break; case R.id.btn_destroy: mThreadsCommunicate.destroy(); break; default: break; } }}
1、这一部分代码运行后DDMS如图:
点击Send按钮后DDMS不变,日志输出如图:
2、退出应用后再次进入应用后DDMS变成这样:
Oh,my god!我们发现多了一个线程,这是为什么???
3、点击destroy按钮后的DDMS:
奇迹发生了,线程少了一个!!!看到这里,我想大家已经知道原因了吧:)
小结1:
在非UI线程中创建Handler(调用Looper.prepare()和Looper.loop())后,在不需要的时候,必需调用Looper.quit()方法;否则,创建该Handler的线程将无法被释放。想想吧,如果每执行一次退出/进入程序操作就多一个线程,那最后,嘿嘿,结果你懂的。。。
第二段代码
在这里,我们只要改一点点代码就可以了:
package com.example.androidtest.thread.communicate;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.util.Log;public class ThreadsCommunicate { private static final String TAG = "ThreadsCommunicate"; private Thread aThread = null; private Handler mHandler = null; public ThreadsCommunicate() { aThread = new AThread(); aThread.start(); } public void sendMsg() { if(null != mHandler) { Log.d(TAG, "sendMsg success!"); mHandler.obtainMessage().sendToTarget(); } else { Log.e(TAG, "sendMsg failed..."); } } public void destroy() { if(null != mHandler) { mHandler.getLooper().quit(); } } private class AThread extends Thread { @Override public void run() { this.setName("myAThread"); Looper.prepare(); Looper.loop();//嘿嘿,就是把这一行从下面移到了这儿,看看结果吧 Log.i(TAG, "AThread run()"); mHandler = new Handler() { @Override public void handleMessage(Message msg) { Log.i(TAG, "Thread name:" + this.getLooper().getThread().getName()); super.handleMessage(msg); } }; super.run(); } }}
改动即是注释部分,结果怎样呢,我们来看看:
1、程序启动后,日志是空的!!!
好吧,我知道你们一定不相信,肯定怀疑我的Logcat坏了,为了打破你们的幻想,我们接着看下面:
2、点击Send按钮后的Logcat
哈哈,这下你们死心了吧,看日志就知道了:mHandler==null。
小结2:
在非UI线程中创建Handler时,创建Handler的时机必须是在Looper.prepare()和Looper.loop()之间,并且所有的有效代码都必需在Looper.loop()之前;因为就实验结果来看,貌似程序是无法执行到Looper.loop()之后的。
结尾
今天因为项目开发,所以在网上在找一些线程间通信的知识,然后自己也粗略看了一些(因为都知道个大概,但细节不确定),但还是没能解决我的一些疑惑;于是我自己动手做了这个小实验,并将实验过程以博文方式记录下来,权当对网上的其它资料的一个补充(当然,若是网上其它还有这方面的文章,那就是我粗心没看到了)。
- 线程间通信之Handler小实验
- 线程间通信之Handler
- 【Android】Handler之线程间通信
- Android线程间通信之Handler
- android线程间通信之handler
- 通信之线程间通信(上)-handler
- Android线程间通信--Handler
- 线程间通信via Handler
- Android 线程间通信------handler
- Android线程间通信机制之Handler Looper
- android学习之handler实现线程间通信
- 面试之handler和线程间通信的方式
- Android子线程间通信之创建handler
- 浅谈Android线程通信之Handler
- Android -- 线程通信之AsyncTask、Handler
- android利用handler线程间的通信
- Android线程间通信机制(Handler Looper )
- Android线程间通信机制(Handler Looper )
- nginx数据结构-ngx_list
- 栈布局.练习题
- 20151217 OCP047 新题库 1-30
- 用一个栈实现另一个栈的排序
- HDOJ 2035 人见人爱 A ^ B
- 线程间通信之Handler小实验
- 多线程执行环境,使用线程安全类---多线程应用实例
- Ubuntu15.10 编译 Android5.0 源码
- 安装msi程序出现2502、2503错误解决方法
- Linux网络监控工具nethogs
- ACM感想
- TortoiseSVN入门篇 - 将已有项目代码加入svn版本控制
- 【LCT维护最大生成树】[HDU5389]GCD Tree
- 第九周 项目三 对称矩阵压缩存储的实现与应用(1)