android之Handler

来源:互联网 发布:mac电池多少钱 编辑:程序博客网 时间:2024/05/17 04:10
android基础之Handler
源代码:http://download.csdn.net/detail/jzp12/4347134

1)继承关系java.lang.Object   ↳android.os.Handler
2)概述:

一个Handler可以允许你发送、处理Message对象和跟线程(thread)想关联的Runnable对象。每个Handler实例都会绑定到一个线程和这个线程的消息队列。当你创建一个新的Handler时,Handler就被绑定到创建它的线程和该线程的消息队列。从创建那一刻起,它将可以开始分发消息和Runnable到消息队列,并且在它们从消息队列出来时执行它们。

Handler主要有两个用途:
(1)安排消息或Runnable在将来的某个时间点被执行。
(2)安排一个动作在别的线程中执行。

3)进一步说明:
Handler主要用于主线程(如UI线程)接收子线程发送的数据, 并使用此数据配合主线程更新UI。

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

4)其它
      Handler中分发消息的一些方法
        post(Runnable)
        postAtTime(Runnable,long)
        postDelayed(Runnable long)
        sendEmptyMessage(int)
        sendMessage(Message)
        sendMessageAtTime(Message,long)
        sendMessageDelayed(Message,long)

        以上post类方法允许你排列一个Runnable对象到主线程队列中,
        sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新

5)示例,子线程发消息到UI线程,通知其更新TextView控制内容。
HandleProjActivity.java
package dongan.hunang.china;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.widget.Button;import android.widget.CheckBox;import android.view.View;import android.view.View.OnClickListener;import android.util.Log;import android.widget.Toast;import android.widget.TextView;//Handler学习示例程序public class HandleProjActivity extends Activity {    /** Called when the activity is first created. */private TextView tv_desire = null;private Button bt_start = null;private Button bt_exit = null;private final static String INFO_TAG = "trace asynchronous";private final static String caskstring = "what do you want";private final static String canswerstring = "meney";private final static int MESSAGE_CODE_01 = 0x0001;private final long delayMillis = 1000; //2sDuckHandle cHandler = null;DuckThread cThread = null;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                // 它安排消息,用以下方法        // post(Runnable)        // postAtTime(Runnable,long)        // postDelayed(Runnable,long)        // sendEmptyMessage(int)        // sendMessage(Message);        // sendMessageAtTime(Message,long)        // sendMessageDelayed(Message,long)        // 以上方法以 post开头的允许你处理Runnable对象        // sendMessage()允许你处理Message对象(Message里可以包含数据,)        cHandler = new DuckHandle();        cThread = new DuckThread();                assert(null != cHandler);        assert(null != cThread);                bt_start = (Button)findViewById(R.id.btstart);        assert(null != bt_start);    bt_start.setOnClickListener(new Button.OnClickListener(){@Overridepublic void onClick(View v) {// TODO Auto-generated method stub//把线程对象放到handler的队列中,线程会马上启动执行,而不必调用 Thread.start//cHandler.post(cThread);//这里也延迟一下,测试一下接口而已//Causes the Runnable r to be added to the message queue, to be run after the specified amount of time elapses. //The runnable will be run on the thread to which this handler is attached.cHandler.postDelayed(cThread, delayMillis);//或者采用手动启动线程//cThread.start();Log.i(INFO_TAG, "post message to queue");}        });            bt_exit = (Button)findViewById(R.id.btexit);        assert(null != bt_exit);    bt_exit.setOnClickListener(new Button.OnClickListener(){@Overridepublic void onClick(View v) {// TODO Auto-generated method stubfinish();Log.i(INFO_TAG, "exit from activity");}        });    }        class DuckHandle extends Handler{@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubLog.i(INFO_TAG, "receive message");switch(msg.what){case MESSAGE_CODE_01://Toast提示消息//Toast.makeText(HandleProjActivity.this, getString(R.string.finish_process_message).toString(),//Toast.LENGTH_SHORT).show();   break;default:break;}Bundle cbundle = msg.getData();String cstring = cbundle.getString(caskstring);tv_desire = (TextView)findViewById(R.id.tobedesire);        assert(null != tv_desire);        tv_desire.setText(tv_desire.getText()+ cstring);        Log.i(INFO_TAG, "finish process message");super.handleMessage(msg);}        }        class DuckThread extends Thread{@Overridepublic void run() {// TODO Auto-generated method stubLog.i(INFO_TAG, "start thread");try {//模拟在子线程耗时的操作                Thread.sleep(delayMillis);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            //发送只包含what值的简单消息//Sends a Message containing only the what value.//cHandler.sendEmptyMessage(MESSAGE_CODE_01);//复杂一点,发个消息Message cmessage = new Message();Bundle cbundle = new Bundle();//store data at Bundlecbundle.putString(caskstring, canswerstring);cmessage.setData(cbundle);cHandler.sendMessage(cmessage);super.run();}        }    }

main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <TextView        android:id="@+id/tobedesire"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:gravity="center"       android:textSize="20sp"       android:background ="#444444"        android:text="@string/what_do_you_want" />    <Button        android:id="@+id/btstart"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_marginTop="5dp"        android:layout_marginLeft="20dp"        android:layout_marginRight="20dp"        android:text="@string/start" />    <Button        android:id="@+id/btexit"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_marginTop="5dp"        android:layout_marginLeft="20dp"        android:layout_marginRight="20dp"        android:text="@string/exit" /></LinearLayout>

strings.xml
<?xml version="1.0" encoding="utf-8"?><resources>    <string name="what_do_you_want">你想要什么:</string>    <string name="app_name">HandleProj</string>    <string name="start">启动</string>    <string name="exit">退出</string>    <string name="finish_process_message">处理消息结束</string></resources>

效果图:



原创粉丝点击