鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 手机系统开发 > android > >

多线程之Handler

来源:互联网 作者:佚名 时间:2013-09-01 08:07
前言 Android的消息传递机制是另外一种形式的事件处理,这种机制主要是为了解决Android应用中多线程的问题,在Android中不允许Activity新启动的线程访问该Activity里的UI组件,这样会导致新启动的线程无法改变UI组件的属性值。但实际开发中,很多地方需要在

前言

  Android的消息传递机制是另外一种形式的“事件处理”,这种机制主要是为了解决Android应用中多线程的问题,在Android中不允许Activity新启动的线程访问该Activity里的UI组件,这样会导致新启动的线程无法改变UI组件的属性值。但实际开发中,很多地方需要在工作线程中改变UI组件的属性值,比如下载网络图片、动画等等。本篇博客主要介绍Handler是如何发送与处理线程上传递来的消息,并讲解Message的几种传递数据的方式,最后均会以小Demo来演示。

 

Handler

  Handler,它直接继承自Object,一个Handler允许发送和处理Message或者Runnable对象,并且会关联到主线程的MessageQueue中。每个Handler具有一个单独的线程,并且关联到一个消息队列的线程,就是说一个Handler有一个固有的消息队列。当实例化一个Handler的时候,它就承载在一个线程和消息队列的线程,这个Handler可以把Message或Runnable压入到消息队列,并且从消息队列中取出Message或Runnable,进而操作它们。

  Handler主要有两个作用:

  • 在工作线程中发送消息。
  • 在UI线程中获取、处理消息。
  •   上面介绍到Handler可以把一个Message对象或者Runnable对象压入到消息队列中,进而在UI线程中获取Message或者执行Runnable对象,所以Handler把压入消息队列有两大体系,Post和sendMessage:

  • Post:Post允许把一个Runnable对象入队到消息队列中。它的方法有:post(Runnable)、postAtTime(Runnable,long)、postDelayed(Runnable,long)。
  • sendMessage:sendMessage允许把一个包含消息数据的Message对象压入到消息队列中。它的方法有:sendEmptyMessage(int)、sendMessage(Message)、sendMessageAtTime(Message,long)、sendMessageDelayed(Message,long)。
  •   从上面的各种方法可以看出,不管是post还是sendMessage都具有多种方法,它们可以设定Runnable对象和Message对象被入队到消息队列中,是立即执行还是延迟执行。

      

    Post

      对于Handler的Post方式来说,它会传递一个Runnable对象到消息队列中,在这个Runnable对象中,重写run()方法。一般在这个run()方法中写入需要在UI线程上的操作。

      在Handler中,关于Post方式的方法有:

       下面通过一个Demo,讲解如何通过Handler的post方式在新启动的线程中修改UI组件的属性:

    1 package com.bgxt.datatimepickerdemo; android.app.Activity; 4 import android.os.Bundle; 5 import android.os.Handler; 6 import android.view.View; 7 import android.widget.Button; 8 import android.widget.TextView; HandlerPostActivity1 extends Activity { 11 private Button btnMes1,btnMes2; 12 private TextView tvMessage; Handler handler=new Handler(); 15 16 @Override onCreate(Bundle savedInstanceState) { 18 super.onCreate(savedInstanceState); 19 setContentView(R.layout.message_activity); 20 21 btnMes1=(Button)findViewById(R.id.btnMes1); 22 btnMes2=(Button)findViewById(R.id.btnMes2); 23 tvMessage=(TextView)findViewById(R.id.tvMessage); 24 btnMes1.setOnClickListener(new View.OnClickListener() { 25 26 @Override onClick(View v) { Thread(new Runnable() { 30 @Override run() { 32 // tvMessage.setText("..."); 33 // 以上操作会报错,无法再子线程中访问UI组件,UI组件的属性必须在UI线程中访问 handler.post(new Runnable() { 36 @Override run() { 38 tvMessage.setText("使用Handler.post在工作线程中发送一段执行到消息队列中,在主线程中执行。"); 39 } 40 }); 41 } 42 }).start(); 43 } 44 }); 45 46 btnMes2.setOnClickListener(new View.OnClickListener() { 47 48 @Override onClick(View v) { 50 new Thread(new Runnable() { 51 @Override run() { 53 // 使用postDelayed方式修改UI组件tvMessage的Text属性值 handler.postDelayed(new Runnable() { 56 57 @Override run() { 59 tvMessage.setText("使用Handler.postDelayed在工作线程中发送一段执行到消息队列中,在主线程中延迟3S执行。"); 60 61 } 62 }, 3000); 63 } 64 }).start(); 65 66 } 67 }); 68 } 69 }

      效果展示:

    网友评论
    <