android: Handler实现异步更新UI

没什么心思去实现模块,所以又看了一点android消息机制。现在写一个Handler的简单Demo。

上小抄:

一、Handler的定义:

          主要接受子线程发送的数据, 并用此数据配合主线程更新UI.

          解释: 当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件, 进行事件分发, 比如说, 你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。  如果此时需要一个耗时的操作,例如: 联网读取数据,    或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,,如果你放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,,会收到Android系统的一个错误提示  "强制关闭".  这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,,Android主线程是线程不安全的, 也就是说,更新UI只能在主线程中更新,子线程中操作是危险的. 这个时候,Handler就出现了.,来解决这个复杂的问题 ,    由于Handler运行在主线程中(UI线程中),  它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传递)Message对象,(里面包含数据)  , 把这些消息放入主线程队列中,配合主线程进行更新UI。

二、Handler一些特点

        handler可以分发Message对象和Runnable对象到主线程中, 每个Handler实例,都会绑定到创建他的线程中(一般是位于主线程),
        它有两个作用: (1):  安排消息或Runnable 在某个主线程中某个地方执行, (2)安排一个动作在不同的线程中执行
      
        Handler中分发消息的一些方法
        post(Runnable)
        postAtTime(Runnable,long)
        postDelayed(Runnable long)
        sendEmptyMessage(int)
        sendMessage(Message)
        sendMessageAtTime(Message,long)
        sendMessageDelayed(Message,long)

        以上post类方法允许你排列一个Runnable对象到主线程队列中,
        sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.
三、Demo
    主要实现一个计数器的东西,按start开始计数,pause停止计数。怎么实现的可以具体log看看线程执行
    xml如下
  
 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:background="#d3d7d4" >
 6 
 7     <TextView
 8         android:id="@+id/TV_MyText"
 9         android:layout_width="wrap_content"
10         android:layout_height="wrap_content"
11         android:layout_alignParentTop="true"
12         android:layout_centerHorizontal="true"
13         android:layout_marginTop="72dp"
14         android:text="@string/hello_world"
15         tools:context=".MainActivity" />
16 
17     <Button
18         android:id="@+id/BT_Start"
19         android:layout_width="wrap_content"
20         android:layout_height="wrap_content"
21         android:layout_below="@+id/TV_MyText"
22         android:layout_centerHorizontal="true"
23         android:layout_marginTop="76dp"
24         android:text="Start" />
25 
26 </RelativeLayout>

Activity

  1 public class MainActivity extends Activity {
  2     private TextView TV_test;
  3     private Button BT_control;
  4     private Handler myHandler;
  5     
  6     public static int count=0;
  7     private int STATE = 0;
  8 
  9     private final int EXECUTE = 1;
 10     private final int QUITE = 2;
 11     @Override
 12     public void onCreate(Bundle savedInstanceState) {
 13         super.onCreate(savedInstanceState);
 14         setContentView(R.layout.activity_main);
 15         
 16         initView();
 17         initHandler();
 18     }
 19     // 当创建一个新的Handler实例时, 它会绑定到当前线程和消息的队列中,开始分发数据
 20     // Handler有两个作用, (1) : 定时执行Message和Runnalbe 对象
 21     // (2): 让一个动作,在不同的线程中执行.
 22 
 23     // 它安排消息,用以下方法
 24     // post(Runnable)
 25     // postAtTime(Runnable,long)
 26     // postDelayed(Runnable,long)
 27     // sendEmptyMessage(int)
 28     // sendMessage(Message)
 29     // sendMessageAtTime(Message,long)
 30     // sendMessageDelayed(Message,long)
 31 
 32     // 以上方法以 post开头的允许你处理Runnable对象
 33     //sendMessage()允许你处理Message对象(Message里可以包含数据,)
 34 
 35     private void initHandler(){
 36         myHandler = new Handler(){
 37             public void handleMessage(android.os.Message msg) {
 38                 switch(msg.what){
 39                 case EXECUTE:
 40                     updateText();
 41                     break;
 42                 case QUITE:
 43                     rebuildText();
 44                     break;
 45                 default:
 46                     super.handleMessage(msg);                    
 47                 }
 48             }
 49 
 50         };
 51     }
 52     
 53     private void initView() {
 54         TV_test = (TextView)findViewById(R.id.TV_MyText);
 55         BT_control = (Button) findViewById(R.id.BT_Start);
 56         
 57         BT_control.setOnClickListener(new OnClickListener() {
 58             MyThread mService;
 59             @Override
 60             public void onClick(View arg0) {
 61                 switch(STATE){
 62                 case 0:
 63                     BT_control.setText("pause");
 64                     STATE++;
 65                     //start service
 66                     mService = new MyThread();
 67                     mService.start();
 68                     break;
 69                 case 1:
 70                     BT_control.setText("start");
 71                     STATE--;
 72                     mService.destroy();
 73                     break;
 74                 default:
 75                     break;
 76                 }
 77             }
 78         });
 79     }
 80     /*
 81      * 这里没用到。。
 82      */
 83     private void rebuildText() {
 84         count=0;
 85         TV_test.setText("count:"+count);
 86     };
 87     
 88     /**
 89      * 更新ui
 90      */
 91     private void updateText(){
 92         TV_test.setText("count:"+count++);
 93     }
 94     
 95     //子线程 获取数据 发送消息
 96     class MyThread extends Thread{
 97         private boolean finished = false;
 98         @Override
 99         public void run() {
100             while(!finished){
101                 try {
102                     sleep(100);
103                 } catch (InterruptedException e) {
104                     e.printStackTrace();
105                 }
106                 Message msg = new Message();
107 //                msg可以通过Bundle来存数据
108 //                msg.setData(data);
109 //                测试用仅仅使用what
110                 msg.what = 1;
111                 myHandler.sendMessage(msg);
112             }
113         }
114         @Override
115         public void destroy() {
116             finished = true;
117         }
118     }
119 }

效果图就不放了。看看代码应该很好理解。

下载demo

参考:http://www.pin5i.com/showtopic-android-handler.html

posted on 2012-11-07 15:36  mathore  阅读(802)  评论(0编辑  收藏  举报