Android的Handler简析

同步自:http://www.elitor.org/?p=201

为什么使用Handler?如何使用Handler?
一个Android程序启动的时候中对应的都有一个主线程Main Thread,也就是UI线程,用于直观显示。当你的程序功能比较复杂,有的时候需要启动别的线程来运行辅助完成一些功能,但是在这些子线程中是不能直接更新UI线程的,否则会抛出一个ViewRootSCalledFromWrongThreadException异常。所以,我们一般的操作是在这个子线程中处理一些事情,处理完了,通过Handler给主线程发送一个message(调用sendMessage()函数完成),而在主线程中将会自动调用handleMessage(Message msg)来处理(没有没什么,这就是Handler的功能),事实上Handler类的这个handleMessage是一个空函数,里面什么事情也没干,查看android的reference便知,所以我们需要自己定义一个类继承Handler,然后override这个函数

总结:
1.需要自己定义一个类继承Handler类,并且override它的handleMessage(Message)函数,可以在这个函数里面实现自己UI的更新等主线程需要的操作。

2.在子线程中通过Handler对象的sendMessage(Message)函数来发送消息给主线程,一旦执行完这个函数,主线程将会自动调用handleMessage(Message)进行操作。
写一个例子:

package org.elitor;
 
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
 
public class HandlerActivity extends Activity
{
    private Button btn = null;
    private MyHandler myHandler = null;
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        Log.d("Thread", "Main Thread...");
        System.out.println("Main Thread: ThreadID---" + Thread.currentThread().getId());
 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        btn = (Button)findViewById(R.id.btn);
        myHandler = new MyHandler();
 
        btn.setText("OK");
        btn.setOnClickListener(new MyBtnClick());
 
    }
 
    //定义一个MyHandler类继承Handler,override其handleMessage(Message)函数
    class MyHandler extends Handler
    {
 
        @Override
        public void handleMessage(Message msg)
        {
            // TODO Auto-generated method stub
            super.handleMessage(msg);
            //打印调试信息
            Log.d("Thread", "MyHandler handleMessage...");
            System.out.println("MyHandler : ThreadID---" + Thread.currentThread().getId());
 
            btn.setText("handler");
            btn.setOnClickListener(new MyBtnClick());
        }
 
    }
 
  //定义一个内部线程类MyThread,实现Runnable接口
    class MyThread implements Runnable
    {
 
        @Override
        public void run()
        {
            // TODO Auto-generated method stub
            Log.d("Thread", "MyThread handleMessage...");
            System.out.println("MyThread at: ThreadID---" + Thread.currentThread().getId());
 
            //下面四句可以理解为封装一个消息
            Message msg = new Message();
            Bundle b = new Bundle();
            b.putString("value1", "test");
            msg.setData(b);
 
            //封装完消息之后,可以通过Handler的对象开始向主线程发送这些消息了
            myHandler.sendMessage(msg);
        }
 
    }
 
    //还定义一个监听器类,用于监听Button按下事件,实现OnClickListener接口即可
    class MyBtnClick implements OnClickListener
    {
        //一旦绑定Button,如果有click事件将会执行onClick函数
        @Override
        public void onClick(View v)
        {
            // TODO Auto-generated method stub
            Log.d("BtnClick", "MyButton Clicked...");
            //可以在点击Button的时候启动线程
            MyThread m = new MyThread();
            new Thread(m).start();
        }
 
    }
 
}

点击btn的时候将启动线程,在线程里通过handler发送一个消息,主线程通过handleMessage(Message)函数来更新UI,例子中哦给简单的更改了btn的名字。另在例子中加入了几个Log,通过Log我们可以看出handleMessage(Message)函数确实和主线程处于同一线程中,而子线程在别的线程中。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值