Handler:搭建UIThread&WorkerThread之间通信的桥梁
2015-03-03 12:16
253 查看
**本博文旨在简单介绍Handler机制,入门级,有基础的朋友可以去看看我的另一篇博文,比较深入一些。
从源码中深入学习Handler,HandlerThread,MessageQueue,Looper**
处理者,处理机。顾名思义,是一种处理消息的机制。
2.定义:
Handler主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外一个部分在消息队列中逐一将消息取出,然后对消息进行处理,也就是发送消息和接收消息不是同步的处理。 这种机制通常用来处理相对耗时比较长的操作。
3.为什么要使用handler:
先把话题岔开来谈谈Java线程机制,Android中的线程主要分为两种:UIThread,即主线程,又称UI线程;另一类是WorkerThread,即自定义线程,或者称为工作线程。
一个Android进程运行起来后,jvm(Java虚拟机)自动启动一个线程,即主线程,在这个线程里原则上可以进行任何合法操作。但在sdk13以后,规定不能再主线程中进行访问网络的操作,因此就需要我们新开一个线程来完成网络操作。
其实这个规定是非常合理的,因为访问网络一般耗时比较长,在主线程里访问网络会造成程序卡顿甚至卡死。不光如此,只要是比较耗时的操作,都不应该在主线程中进行。至于为什么会出现卡顿,则显而易见,这里就不说了,不懂的朋友请留言,我看到后会及时回复的。
这样,如果我们的程序存在耗时较长的操作,那么我们必须开启新线程。这么一来,我们的程序里就同时存在了UIThread线程和一个或者多个WorkerThread。然后,线程之间如何通信,成了一个亟待解决的问题。
这里我们的handler就派上大用场了。
4.线程间通信举例
这里就简单叙述一下,不贴代码了,很简单。比如我们让主线程x(x是个随机数)秒后进行一次耗时操作,比如从网络上下载一个MP3文件,这是由于x是随机的,我们不知道具体哪个时刻进行网络操作,一个很直观的解决方法就是,当主线程x秒之后,通过某种方式通知WorkerThread进行下载MP3操作,这里的某种方式就是Handler。
5.handler的使用分类
handler使用场景主要有两种:
1>UIThread通过handler通知WorkerThread进行某项操作;
2>WorkerThread通过handler通知UIThread进行某项操作;
6.handler的一些重要方法的介绍
7.线程间的通信
(通过这个例子,咱们同时熟悉一下上面提到的函数的使用方法)
7.1 UI线程通知Worker线程
以上代码的效果就是点击TextView后主线程通过Worker线程的Handler发送一个消息给Worker线程对应的消息队列,Worker线程的Handler取出该消息时显示了一个Toast。这就是 UI线程通知Worker线程。
下面让Worker线程通知UI线程
和上面的是相反的。自己理解了。。
看到这里,想必大家已经明白了Handler的用法,其中最主要的一点就要搞懂:Handler对象是在哪个线程中申请的,我们就可以利用它向哪个线程中发送消息!!!!!
至于你想问中间的Looper.looper(),消息队列等等都是干啥的,那就去我开篇提到的那个博文中去寻找答案吧,写的还算详细,大家可以去参考。
最后声明一点:我上面举的两个例子,可以说是线程间通信中最简单,最本质的例子了,我敢说网上基本所有的线程通信教程都会提及这两个例子。如果你第一遍没看懂,一定要仔细琢磨一下,多思考,是学Android必备的基本素养。
好了,今天就到这里。
从源码中深入学习Handler,HandlerThread,MessageQueue,Looper**
概念解析
1.英文释义:处理者,处理机。顾名思义,是一种处理消息的机制。
2.定义:
Handler主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外一个部分在消息队列中逐一将消息取出,然后对消息进行处理,也就是发送消息和接收消息不是同步的处理。 这种机制通常用来处理相对耗时比较长的操作。
3.为什么要使用handler:
先把话题岔开来谈谈Java线程机制,Android中的线程主要分为两种:UIThread,即主线程,又称UI线程;另一类是WorkerThread,即自定义线程,或者称为工作线程。
一个Android进程运行起来后,jvm(Java虚拟机)自动启动一个线程,即主线程,在这个线程里原则上可以进行任何合法操作。但在sdk13以后,规定不能再主线程中进行访问网络的操作,因此就需要我们新开一个线程来完成网络操作。
其实这个规定是非常合理的,因为访问网络一般耗时比较长,在主线程里访问网络会造成程序卡顿甚至卡死。不光如此,只要是比较耗时的操作,都不应该在主线程中进行。至于为什么会出现卡顿,则显而易见,这里就不说了,不懂的朋友请留言,我看到后会及时回复的。
这样,如果我们的程序存在耗时较长的操作,那么我们必须开启新线程。这么一来,我们的程序里就同时存在了UIThread线程和一个或者多个WorkerThread。然后,线程之间如何通信,成了一个亟待解决的问题。
这里我们的handler就派上大用场了。
4.线程间通信举例
这里就简单叙述一下,不贴代码了,很简单。比如我们让主线程x(x是个随机数)秒后进行一次耗时操作,比如从网络上下载一个MP3文件,这是由于x是随机的,我们不知道具体哪个时刻进行网络操作,一个很直观的解决方法就是,当主线程x秒之后,通过某种方式通知WorkerThread进行下载MP3操作,这里的某种方式就是Handler。
5.handler的使用分类
handler使用场景主要有两种:
1>UIThread通过handler通知WorkerThread进行某项操作;
2>WorkerThread通过handler通知UIThread进行某项操作;
6.handler的一些重要方法的介绍
//handler处理消息的函数 public void handleMessage(Message msg) { } //handler获得一个消息的函数 public final Message obtainMessage(int what) { return Message.obtain(this, what); } //handler向其所在线程对应的消息队列中发送一段执行代码, public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); } //和上一个函数一样的功能,只不过是在特定的时间发送 public final boolean postAtTime(Runnable r, long uptimeMillis) { return sendMessageAtTime(getPostMessage(r), uptimeMillis); } //在特定的延迟后发送 public final boolean postDelayed(Runnable r, long delayMillis) { return sendMessageDelayed(getPostMessage(r), delayMillis); }
后面我会举个例子来使用这些函数,帮助大家更好的理解这些函数的作用
7.线程间的通信
(通过这个例子,咱们同时熟悉一下上面提到的函数的使用方法)
7.1 UI线程通知Worker线程
public class MainActivity extends Activity implements OnClickListener{ //定义handler private Handler handler; private WorkerTread workerTread=new WorkerTread(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //启动workerthread workerTread.start(); setContentView(R.layout.activity_main); TextView textView=(TextView)findViewById(R.id.o); textView.setOnClickListener(this); } public class WorkerTread extends Thread{ @Override public void run() { Looper.prepare(); //New Handler() handler=new Handler(){ @Override //自定义处理消息的函数 public void handleMessage(Message msg) { Toast.makeText(MainActivity.this, "WorkerThread", Toast.LENGTH_SHORT).show(); } }; Looper.loop(); } } @Override public void onClick(View v) { //点击时获得一个消息并发送给handler所在的线程 handler.obtainMessage().sendToTarget(); }
以上代码的效果就是点击TextView后主线程通过Worker线程的Handler发送一个消息给Worker线程对应的消息队列,Worker线程的Handler取出该消息时显示了一个Toast。这就是 UI线程通知Worker线程。
下面让Worker线程通知UI线程
public class MainActivity extends Activity implements OnClickListener{ //在主线程中new出一个新的Handler对象,该对象属于UI线程 private Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { //接受消息后打印一行字“UITread" Toast.makeText(MainActivity.this, "UIThread", Toast.LENGTH_SHORT).show(); }; }; private WorkerTread workerTread=new WorkerTread(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView=(TextView)findViewById(R.id.o); textView.setOnClickListener(this); } public class WorkerTread extends Thread{ @Override public void run() { //通过UI线程的Handler向UI线程对应的消息队列中发送一个消息 handler.obtainMessage().sendToTarget(); } } @Override //当点击事件发生时,启动workerThread。 public void onClick(View v) { workerTread.start(); } }
和上面的是相反的。自己理解了。。
看到这里,想必大家已经明白了Handler的用法,其中最主要的一点就要搞懂:Handler对象是在哪个线程中申请的,我们就可以利用它向哪个线程中发送消息!!!!!
至于你想问中间的Looper.looper(),消息队列等等都是干啥的,那就去我开篇提到的那个博文中去寻找答案吧,写的还算详细,大家可以去参考。
最后声明一点:我上面举的两个例子,可以说是线程间通信中最简单,最本质的例子了,我敢说网上基本所有的线程通信教程都会提及这两个例子。如果你第一遍没看懂,一定要仔细琢磨一下,多思考,是学Android必备的基本素养。
好了,今天就到这里。
相关文章推荐
- 关于Android中的Handler,Message,Looper,MessageQueue和Thread的之间的通信机制
- Android中子线程和UI线程之间通信的方式(Handler与Thread-附源码)
- 《Handler: Activity 之间通过 Handler 通信》 & 《通过Handler更新UI》
- WorkerThread与MainThread之间通过Handler进行最简单的消息传递
- Android--Handler+Looper+MessageQueue+Thread线程之间的通信
- 《Handler: Activity 之间通过 Handler 通信》 & 《通过Handler更新UI》
- 《Handler: Activity 之间通过 Handler 通信》 & 《通过Handler更新UI》
- Android中Handler、Thread(HanlderThread)、Runnable之间的关系
- Handler: Activity 之间通过 Handler 通信
- Handler,Looper,Thread之间的关系
- android中Thread、handler(Handler Thread)、Runnable之间的关系
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- (转)解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- Android中Handler、Thread(HanlderThread)、Runnable之间的关系
- 解析Android消息处理机制 ——Handler/Thread/Looper & MessageQueue
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- HandlerThread&Looper&MessageQueue
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- 解析Android消息处理机制 ——HandlerThread/Looper & MessageQueue & Message
- ArrayList 和数组之间的一些转换 Handler的主线程与子线程通信 内部类的使用