概念:
MessageQueue:消息队列,存放消息的地方,按照FIFO(先进先出)规则执行,每一个线程只可以拥有一个MessageQueue,在创建looper对象会创建一个MessageQueue对象
Message:消息对象,MessageQueue中存放的对象,一个MessageQueue中可以包含多个Message对象,可以通过Message.obtain()或Message.obtainMessage()获取Message对象,但是并不一定是直接创建一个新的实例,而是先从消息池中看有没有可用的Message实例,存在则直接取出返回这个实例,如果消息池中没有可用的Message实例,则才用给定的参数创建一个Message对象,调用removeMessage()将message对象从MessageQueue中删除,同时放入到消息池中
Looper:操作MessageQueue.一个Looper对应一个MessageQueue.通过调用Loop.myLooper()可以获得当前线程的Looper对象.Looper从MessageQueue中取出Message后,交给Handler的handleMessage()进行处理.处理完后,调用Message.recycle()将其放入消息池中
Handler:消息的处理者,handler负责将需要传递的信息封转成Message对象,然后调用sendMessage()方法将消息放入到MessageQueue中,当MessageQueue循环到该Message,
调用相应的Handler对象的HandleMessage()方法对其进行处理,Handler都可以共享同一个Looper和MessageQueue
handler类允许你发送消息和处理线程消息队列中的消息及runnable对象。handler实例都是与一个线程和该线程的消息队列一起使用,一旦创建了一个新的handler实例,系统就把该实例与一个线程和该线程的消息队列捆绑起来,这将可以发送消息和runnable对象给该消息队列,并在消息队列出口处处理它们。
handler类有两种主要用途:1。按照时间计划,在未来某时刻,对处理一个消息或执行某个runnable实例。2。把一个对另外线程对象的操作请求放入消息队列中,从而避免线程间冲突。
时间类消息通过如下方法使用: post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message), sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long)
methods. post之类函数可以传输一个runnable对象给消息队列,并在到达消息队列后被调用。sendmessage之类函数可以传送一个包含数据的message对象,该message对象可以被Handler类的handleMessage(Message) 方法所处理。
post之类函数和sendmessage之类的函数都可以指定消息的执行时机,是立即执行、稍后一段时间执行,还是在某个确定时刻执行。这可以用来实现超时、消息或其他时间相关的操作。
当一个进程启动时,主线程独立执行一个消息队列,该队列管理着应用顶层的对象(如:activities、broadcast receivers等等)和所有创建的窗口。你可以创建自己的一个线程,并通过handler来与主线程进行通信。这可以通过在新的线程中调用主线程的handler的post和sendmessage操作来实现。
1、布局文件main.xml
- <ProgressBar
- android:id="@+id/myProBar"
- style="?android:attr/progressBarStyleHorizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:visibility="gone"/>
- <Button
- android:id="@+id/btnStart"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/btnStart"/>
2、Activity文件中的代码如下
- //声明控件变量
- ProgressBarproBar;
- ButtonbtnStart;
- inti=0;
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- roBar=(ProgressBar)this.findViewById(R.id.myProBar);
- btnStart=(Button)this.findViewById(R.id.btnStart);
- btnStart.setOnClickListener(newView.OnClickListener(){
- @Override
- publicvoidonClick(Viewarg0){
- proBar.setVisibility(View.VISIBLE);
- updateBarHandler.post(updateThread);
- }
- HandlerupdateBarHandler=newHandler(){
- @Override
- publicvoidhandlerMessage(Messagemsg){
- proBar.setProgress(msg.arg1);
- updateBarHandler.post(updateThread);
- }
- };
- RunnableupdateThread=newRunnable()
- {
- @Override
- publicvoidrun(){
- i+=10;
- Messagemsg=updateBarHandler.obtainMessage();
- msg.arg1=i;
- try{
- Thread.sleep(1000);
- }
- catch(InterruptedExceptione){
- e.printStackTrace();
- }
- updateBarHandler.sendMessage(msg);
- if(i==100)
- {
- updateBarHandler.removeCallbacks(updateThread);
- }
- }
- };
- });
- }
3、运行结果
1.Handler与线程
实际上Handler与Activity处于同一线程当中
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- Handlerhandler=newHandler();
- handler.post(r);
- setContentView(R.layout.main);
- System.out.println("activity--->"+Thread.currentThread().getId());
- System.out.println("activity--->"+Thread.currentThread().getName());
- }
- Runnabler=newRunnable(){
- @Override
- publicvoidrun(){
- System.out.println("handler--->"+Thread.currentThread().getId());
- System.out.println("handlerName--->"+Thread.currentThread().getName());
- try{
- Thread.sleep(10000);
- }catch(InterruptedExceptione){
- e.printStackTrace();
- }
- }
handersetCotentView()之前,所有要等待10秒,Activity中的内容才显示处理,并且输出的id和name相同,则说明Handler没有启动新线程,
2.在新线程当中处理消息方法,(需要使用Looper对象,改对象提供了循环的从队列中取消息的这种功能),并使用Bundle
- packagewei.cao.handler;
- importandroid.app.Activity;
- importandroid.os.Bundle;
- importandroid.os.Handler;
- importandroid.os.HandlerThread;
- importandroid.os.Looper;
- importandroid.os.Message;
- publicclassHandler_03extendsActivity{
- @Override
- protectedvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- System.out.println("Activity--->"+Thread.currentThread().getId());
- HandlerThreadhandlerThread=newHandlerThread("handler_thread");
- handlerThread.start();
- MyHandlermyHandler=newMyHandler(handlerThread.getLooper());
- Messagemsg=myHandler.obtainMessage();
- Bundleb=newBundle();
- b.putString("name","wei_cao");
- b.putInt("age",10);
- msg.obj="abc";
- msg.setData(b);
- msg.sendToTarget();
- }
- classMyHandlerextendsHandler
- {
- publicMyHandler(Looperlooper)
- {
- super(looper);
- }
- @Override
- publicvoidhandleMessage(Messagemsg){
- Stringstr=(String)msg.obj;
- Bundleb=msg.getData();
- Stringname=b.getString("name");
- intage=b.getInt("age");
- System.out.println("nameis"+name+"ageis"+age+"stris"+str);
- System.out.println("Handler--->"+Thread.currentThread().getId());
- System.out.println("handleMessage");
- }
- }
- }