您的位置:首页 > 产品设计 > UI/UE

Android 多线程编程:Handler消息传递机制—刷新UI主界面

2015-09-09 12:06 483 查看

一、为什么使用Handler

  当一个Activity运行的时候,会开启一条主线程,主线程主要负责处理与UI相关的事件,主线程不允许其他子线程操控它,更新UI界面。既然不允许我们在子线程中操控UI界面,那么,像我们平时所见的点击获取验证码,不断更新UI界面的操作又怎样实现的呢?这里就用到了我们的Handler消息传递的机制。

二、Handler消息传递机制介绍

Handler类的主要作用有两个:

1、在新启动的线程中发消息。

2、在主线程中获取、处理消息。

也就是线程发消息给主线程,在handler中存在一个MessageQueue(消息队列),线程的消息发给了MessageQueue,我们再通过Handler类中的handleMessage方法重写进行相关操作。Handler会不断的从MessageQueue中获取并处理消息。当然除了能从线程向主线程发消息,我们也可以从主线程向线程发消息,只是这种情况不常见,一般不会这样做。

补充

Handler 机制原理

三、使用实例

子线程向主线程发消息

1、开启一个新的线程,在新的线程中new一个Message,设置Message,并由发送Message

2、主线程中接收Handler,并进行UI的更新操作

[code]package com.example.newjc;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener{
    private Button mbtn_second;
    private Handler handler=new Handler(){

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case TIME_DESC:
                String s=(String) msg.obj;
                mbtn_second.setText(s);
                break;

            default:
                break;
            }

        }

    };
    public static final int TIME_DESC=0x22;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mbtn_second=(Button) findViewById(R.id.bt_second);
        mbtn_second.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

    new Thread (new Runnable() {

        @Override
        public void run() {
        int count=60;
            while(count>0){
                count--;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Message msg=new Message();
                msg.obj=count+"秒";
                msg.what=TIME_DESC;
             handler.sendMessage(msg);
            }

        }
    }).start();

    }

}





为了简化操作,我们对以上代码进行修改,采用递归思想来实现同样效果

注意:这里的代码并没有用到子线程,纯粹是handler的一种使用方式。

[code]@Override
    public void onClick(View v) {
        count=60;
        //发送一个空消息
        handler.sendEmptyMessage(TIME_DESC);
    }


[code]private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case TIME_DESC:
                count--;
                mbtn_second.setText(count + "秒");
                if (count > 0) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    handler.sendEmptyMessage(TIME_DESC);
                }
                break;
            default:
                break;
            }
        }
    };


主线程给子线程发消息

[code]public class MainActivity extends Activity implements OnClickListener {
    private Button mbtn_second;
    private Button mbtn_second2;
    private int count;
    private  Mythread thread;
    public static final int TIME_DESC = 0x22;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mbtn_second = (Button) findViewById(R.id.bt_second);
        mbtn_second2 = (Button) findViewById(R.id.bt_second2);
        mbtn_second.setOnClickListener(this);
        mbtn_second2.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        //count = 60;
        //handler.sendEmptyMessage(TIME_DESC);
        switch (v.getId()) {
        case R.id.bt_second:
             thread=new Mythread();
             thread.start();
            break;
        case R.id.bt_second2:
//因为handler需要时间创建,因此不能直接将下面的代码放在 //thread.start();下面,放在他下面会报空指针

             thread.handler.sendEmptyMessage(0);
            break;
        default:
            break;
        }

    //   thread.handler.sendEmptyMessage(0);
    }
    class Mythread extends Thread{
    private Handler handler;
      @Override
    public void run() {
    //handler—send-MessageQueue-looper读取—hangleMessage操作
    //looper是主线程中默认使用,因此在子线程向主线程发消息的时候没有添加
    //但是子线程不具有,因此必须写出
        Looper.prepare();
        handler=new Handler(){          
        @Override
        public void handleMessage(Message msg) {
            Log.d("主线程给子线程", "主线程给子线程");            
        }
        };
        Looper.loop();
    }
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: