Android菜鸟的成长笔记(12)——Handler、Loop、MessageQueue

转载 2014年04月16日 09:19:17
当一个程序第一次启动时,Android会启动一条主线程(Main Thread),主线程主要负责处理与UI相关的事件,如按键事件、触屏事件、绘图事件,主线程也被称为UI线程。
UI的操作只能是通过主线程来操作,为了解决多线程操作UI的问题,就用到了Handler类。
一、Handler类
Handler类的作用有两个:
1、在新启动的线程中发送消息。
2、在主线程中获取、处理消息。
例如:
  1. package com.example.testlistener;  
  2.   
  3. import java.util.Timer;  
  4. import java.util.TimerTask;  
  5.   
  6. import android.app.Activity;  
  7. import android.content.res.Configuration;  
  8. import android.os.Bundle;  
  9. import android.os.Handler;  
  10. import android.os.Message;  
  11. import android.view.View;  
  12. import android.view.View.OnClickListener;  
  13. import android.view.View.OnLongClickListener;  
  14. import android.widget.Button;  
  15. import android.widget.EditText;  
  16. import android.widget.Toast;  
  17.   
  18. public class MainActivity extends Activity {  
  19.     EditText txt;  
  20.     final Handler hander = new Handler(){  
  21.         public void handleMessage(android.os.Message msg) {  
  22.             if(msg.what == 0x1234){  
  23.                 Toast.makeText(MainActivity.this, msg.arg1 + ""1000).show();  
  24.             }  
  25.         };  
  26.     };  
  27.     @Override  
  28.     protected void onCreate(Bundle savedInstanceState) {  
  29.         super.onCreate(savedInstanceState);  
  30.         setContentView(R.layout.activity_main);  
  31.           
  32.         new Timer().schedule(new TimerTask() {  
  33.             int i = 0;  
  34.             @Override  
  35.             public void run() {  
  36.                 i++;  
  37.                 Message msg = new Message();  
  38.                 msg.what = 0x1234;  
  39.                 msg.arg1 = i;  
  40.                 hander.sendMessage(msg);  
  41.             }  
  42.         }, 02000);  
  43.     }  
  44.       
  45. }  
Message是Hander接收和处理的消息对象。通过向Message中添加消息,将消息放入消息队列MessageQueue,然后通过Looper方法读取MessageQueue。
打开Android系统源码可以看到:
  1. private Looper() {  
  2.     mQueue = new MessageQueue();  
  3.     mRun = true;  
  4.     mThread = Thread.currentThread();  
  5. }  
程序创建时Looper会在它的构造器中创建MessageQueue对象。
handlerMessage方法位于主线程,可以处理UI.
二、Handler、Looper、MessageQueue的工作原理
Looper:每个线程只有一个Looper,负责管理MessageQueue,会不断地从MessageQueue中取出消息,并将消息分给对应的Handler处理。
MessageQueue:由Looper负责管理,采用先进先出的方式管理Message(消息队列).
Handler:把消息发送给Looper管理的MessageQueue并负责处理Looper分给它的消息。
为了保证当前线程中有Looper对象,有如下两种情况:
1、主UI线程中,系统已经初始化了一个Looper对象,因此程序直接创建Handler即可。
2、自己定义的子线程,必须先创建一个Looper对象,并启动它。
例如:将上面的例子加以修改
  1. package com.example.testlistener;  
  2.   
  3. import java.util.Timer;  
  4. import java.util.TimerTask;  
  5.   
  6. import android.app.Activity;  
  7. import android.content.res.Configuration;  
  8. import android.os.Bundle;  
  9. import android.os.Handler;  
  10. import android.os.Looper;  
  11. import android.os.Message;  
  12. import android.view.View;  
  13. import android.view.View.OnClickListener;  
  14. import android.view.View.OnLongClickListener;  
  15. import android.widget.Button;  
  16. import android.widget.EditText;  
  17. import android.widget.Toast;  
  18.   
  19. public class MainActivity extends Activity {  
  20.     EditText txt;  
  21.     Button bt;  
  22.     TestThread testThread;  
  23.     int j = 0;  
  24.     final Handler hander = new Handler(){  
  25.         public void handleMessage(android.os.Message msg) {  
  26.             if(msg.what == 0x1234){  
  27.                 Toast.makeText(MainActivity.this, msg.arg1 + ""1000).show();  
  28.             }  
  29.         };  
  30.     };  
  31.     @Override  
  32.     protected void onCreate(Bundle savedInstanceState) {  
  33.         super.onCreate(savedInstanceState);  
  34.         setContentView(R.layout.activity_main);  
  35.         txt = (EditText) findViewById(R.id.txt);  
  36.         bt = (Button) findViewById(R.id.bn);  
  37.         testThread = new TestThread();  
  38.         testThread.start();  
  39.         bt.setOnClickListener(new OnClickListener() {  
  40.               
  41.             @Override  
  42.             public void onClick(View arg0) {  
  43.                 j++;  
  44.                 Message msg = new Message();  
  45.                 msg.what = 0x1000;  
  46.                 msg.arg1 = j;  
  47.                 testThread.thander.sendMessage(msg);  
  48.             }  
  49.         });  
  50.           
  51.         new Timer().schedule(new TimerTask() {  
  52.             int i = 0;  
  53.             @Override  
  54.             public void run() {  
  55.                 i++;  
  56.                 Message msg = new Message();  
  57.                 msg.what = 0x1234;  
  58.                 msg.arg1 = i;  
  59.                 hander.sendMessage(msg);  
  60.             }  
  61.         }, 02000);  
  62.     }  
  63.       
  64.     //自定义子线程  
  65.     class TestThread extends Thread{  
  66.         public Handler thander;  
  67.         @Override  
  68.         public void run() {  
  69.             //创建一个Looper对象  
  70.             Looper.prepare();  
  71.             thander = new Handler(){  
  72.                 @Override  
  73.                 public void handleMessage(Message msg) {  
  74.                     if(msg.what == 0x1000){  
  75.                         System.out.println("j = " + msg.arg1);  
  76.                         //txt.setText(msg.arg1 + "");  
  77.                     }  
  78.                 }  
  79.             };  
  80.             //启动Looper  
  81.             Looper.loop();  
  82.         }  
  83.     }  
  84.       
  85. }  
运行结果:

相关文章推荐

Android菜鸟的成长笔记(12)——Handler、Loop、MessageQueue

当一个程序第一次启动时,Android会启动一条主线程(Main Thread),主线程主要负责处理与UI相关的事件,如按键事件、触屏事件、绘图事件,主线程也被称为UI线程。 UI的操作只能是通过主线...

Android菜鸟的成长笔记——可爱的小闹钟

转载至:http://blog.csdn.net/dawanganban/article/details/19967445 (谢谢阳关小强的分享) 摘要: 这一篇主要使用系统为我们提供的...
  • zxg19
  • zxg19
  • 2014-05-29 20:08
  • 506

Android菜鸟的成长笔记(8)——Intent与Intent Filter(上)

Intent代表了Android应用的启动“意图”,Android应用将会根据Intent来启动指定组件,至于到底启动哪个组件,取决于Intent的各个属性。 一、显式的Intent 明确...

Android菜鸟的成长笔记(28)——Google官方对Andoird 2.x提供的ActionBar支持

在Google官方Android设计指南中(链接:http://www.apkbus.com/design/get-started/ui-overview.html)有一个新特性就是自我标识,也就是宣...

Android菜鸟的成长笔记(20)——IntentService

前面介绍的Service在官方文档介绍中说Service存在着如下两个问题: 1.A Service is not a separate process. The Service obj...

Android菜鸟的成长笔记(6)——剖析源码学自定义主题Theme

还记得在Android菜鸟的成长笔记(3)中我们曾经遇到了一个问题吗?"这个界面和真真的QQ界面还有点不同的就是上面的标题myFirstApp,怎么去掉这个标题呢?",当时我直接在AndroidMai...

Android菜鸟的成长笔记——初识Activity

一、         产生Log文件 1、 程序异常退出,uncaused exception; 2、 程序强制关闭,Force Closed; 3、 程序无响应,Application No ...

Android菜鸟的成长笔记(3)——给QQ登录界面说So Easy

我们前面已经做了第一个Android应用程序,虽然有点像QQ的登录界面,但是很多地方还是很难看,这一篇咱们来将这个界面做成一个标准的商业界面,并一起来了解Android中的代码运行的原理。 好吧...

Android菜鸟的成长笔记(9)——Intent与Intent Filter(下)

接着上一篇的内容,下面我们再来看看Intent的Data与Type属性。 一、Data属性与Type属性 Data属性通常用于向Action属性 提供操作的数据,Data属性接受一个Uri...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)