Handle的一些用法

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-31 20:16   31   0

转载:http://www.apkbus.com/blog-815579-61293.html

只是给自己做一下笔记而已。


1、Handler(消息处理者)

<1>使用handeler的步骤:
(1)创建一个Handler;
   
  1. private Handler handler = new Handler(){
  2. //用来接收和处理从子线程发送回来的信息,在主线程中接收
  3. public void handleMessage(Message msg) {
  4. String content = (String) msg.obj;
  5. int arg1 = msg.arg1;
  6. int arg2 = msg.arg2;
  7. int what = msg.what;
  8. textView.setText(content+arg1 +arg2 +what);
  9. };
  10. };
(2)在需要用到数据传输的地方通过handler得到message对象,通过message携带要传输的数据;
    
  1. //1.通过handler得到一个信息
  2. Message message = handler.obtainMessage();
  3. //2.通过这个信息,携带数据
  4. message.obj = content;
  5. message.arg1 = 100;
  6. message.arg2 = 200;
  7. message.what = 300;
取Message对象的最好方法是调用Message.obtain()或者Handler.obtainMessage(), 这样是从一个可回收对象池中获取Message对象。
(3)直接通过handler发送消息,到主线程;
    
  1. //3.利用了handler发送消息,从子线程发送到了主线程
  2. handler.sendMessage(message);
(4)通过重写handleMessage()方法,接收传输过来的数据。
    
  1. //用来接收和处理从子线程发送回来的信息,在主线程中接收
  2. public void handleMessage(Message msg) {
  3. String content = (String) msg.obj;
  4. int arg1 = msg.arg1;
  5. int arg2 = msg.arg2;
  6. int what = msg.what;
  7. textView.setText(content+arg1 +arg2 +what);
  8. };
<2>handleMessage():在主线程中,构造Handler对象时,重写此方法;
    
  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. ......
  4. }
<3>sendEmptyMessage():用在子线程中,发送空消息;
    
  1. //1.发送一个空消息(不用构造message对象,而是直接给一个消息标记)
  2. handler.sendEmptyMessage(1);
<4>sendMessage():用在工作线程中,立即发送消息;
   
  1. handler.sendMessage(message);
  2. //发送延迟消息 3000:延迟的时间(单位是毫秒)
  3. //handler.sendMessageDelayed(message, 3000);
  4. //发送延迟空消息
  5. //handler.sendEmptyMessageDelayed(5, 3000);
2、Message(消息)
<1> 使用Message需要注意4点:
(1)Message虽然也可以通过new来获取,但是通常使用Message.obtain()或Handler.obtainMessage()方法来从消息池中获得空消息对象,以节省资源;
   
  1. //2.发送一个带message的信息
  2. Message message = handler.obtainMessage();
  3. //获取到一个信息对象
  4. Message message2 = Message.obtain();
(2)如果一个Message只需要携带简单的int型数据,应优先使用arg1和arg2属性来传递数据,这样比其他方式节省内存;
   
  1. message.arg1 = 2; //arg1和arg2都是用来传输整形
  2. message.arg2 = 3;
(3)尽可能使用Message.what来标识信息,以便用不同的方式处理Message。
   
  1. message.what = 4; //也是用来传输整数类型,但是一般用来传输message标记
(4)如果需要从工作线程返回很多数据信息,可以借助Bundle对象将这些数据集中到一起,然后存放到obj属性中,再返回到主线程。
<2>arg1:用来存放整型数据
<3>arg2:用来存放整形数据
<4>obj:用来存放Object数据
<5>what:用于指定用户自定义的消息代码,便于主线程接收后,根据消息代码不同而执行不同的操作
3、Thread(将消息发送给主线程)
4、Handler运行原理
<1> Handler、Looper、Message、MessageQueue之间的关系:
Handler,Looper和MessageQueue的三角关系
<2> Looper和MessageQueue一一对应,创建一个Looper的同时,会创建一个MessageQueue; 而Handler与它们的关系,只是简单的聚集关系,即Handler里会引用当前线程里的特定Looper和MessageQueue;
在一个线程中,只能有一个Looper和MessageQueue,但是可以有多个Handler,而且这些Handler可以共享一个Looper和MessageQueue;
<3> Message被存放在 MessageQueue中,一个 MessageQueue中可以包含多个Message对象。
【备注:】
(1) Looper对象用来为一个线程开启一个消息循环,从而操作MessageQueue;
(2) 默认情况下,Android创建的线程没有开启消息循环,但是主线程例外。
(3) 系统自动为主线程创建Looper对象,开启消息循环;
(4) 所以主线程中使用new来创建Handler对象。而子线程中不能直接new来创建Handler对象就会异常。
(5)利用handler把数据从主线程中发送到子线程:
在主线程中,自带一个有loop对象,并且这个loop对象在循环工作;
但是在子线程中接收数据之前先调用Looper.prepare(),再调用Looper.loop()方法。
(6) 子线程中创建Handler对象,步骤如下:
Looper.prepare();
Handler handler = new Handler() {
//handlemessage(){}
}
Looper.loop();
<4> Looper:消息泵,不断地从MessageQueue中抽取Message执行。一个MessageQueue需要一个Looper
<5> Hanlder:消息处理者
(1) 在新启动的工作线程中发送消息
(2) 在主线程中获取、并处理消息
<6> MeessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行
<7> Message:消息,包含线程处理的数据和消息参数
<8> Thread:通过主线程的handler对象发送消息给主线程,并更新UI
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP