天天看点

Handler消息机制之基础代码篇

在主线程中直接写耗时操作的话很容易引起ANR异常,所以我们都把耗时操作写在子线程中去完成,但执行完之后,想要更新页面,又不允许在子线程中去更改页面 --  异步任务 或加载器解决了此问题。除了以上两种解决方式外,使用Thread +Handler也可实现上述效果。
           

“Handler的作用:注意是在android.os包下的类

(1)、发送并处理消息

(2)、可以排队执行一系列的动作

此类介绍Handler的最最最基本使用

一. 发送空消息

static final int LOADING_START= ;
    static final int LOADING_FINISH=;

    Button  textView;

       /*
        *  创建Handler对象,
        * */
    Handler handler = new Handler(){

           //此处接收所有有当前handler对象通过send方法发出的消息
           //参数代表接收到的消息对象
        @Override
        public void handleMessage(Message msg) {
         //通过msg对象的what属性取出当前接收到的消息的标识
            if (msg.what == LOADING_FINISH) {

                textView.setText("我要当大牛");
            }
            super.handleMessage(msg);
        }
    };
           
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (Button) findViewById(R.id.textview);

    } 
           
//模拟按钮  进行耗时操作
    public  void  click(View v) {

        new Thread(){
            @Override
            public void run() {

                try {
                    Thread.sleep();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //更新页面操作
                /*
                 * 如果直接在子线程执行更改UI的操作的话
                 * 会抛出CalledFromWrongThreadException
                 * 引起程序的崩溃
                 * 原因:规定子线程不允许操作UI页面
                 *
                 * 注意:Toast,对话框这种弹出窗口的show方法也算是UI操作
                 * */
//              textView.setText("zss");
                //  Toast.makeText(MainActivity.this,"哈哈先生",Toast.LENGTH_SHORT);
                /*

                 * 不让在子线程中写,那么我就想办法把我要干的事情传出去,在某一个位置
                 * 接收到我在子线程中传出的事情,并执行   通过Handler发送消息
                * */

                //发送一个空消息
                handler.sendEmptyMessage(LOADING_FINISH);
            }
        }.start();
    }
           

完整代码已贴出,附有详细注释,上述代码只是发送了一个简单的空消息。

补充知识点:对于上述发送的消息,结构为 耗时+发送的结构。现在我们改为 发送 + 耗时 +发送 代码如下:

只需在如下方法中添加这几行代码即可

public void handleMessage(Message msg) {
         //通过msg对象的what属性取出当前接收到的消息的标识
            if (msg.what == LOADING_FINISH) {

                textView.setText("我要当大牛");
            }else if(msg.what == LOADING_START){

                 textView.setText("等待时间");
            }
            super.handleMessage(msg);
        }
           
new Thread(){
            @Override
            public void run() {

                handler.sendEmptyMessage(LOADING_START);

                try {
                    Thread.sl
           

剩余代码都是一样的,就不完整贴出了。

二. 发送非空消息

** //通过Handler发送非空消息

/*

* 当想要发送非空消息的时候,

* 1.封装要发送的消息对象

* 在初始化Message对象的时候,推荐使用以下的初始化方式

* 原因:下面的方式比new 的方式效率高,节省内存“

* /*

//模拟按钮  进行耗时操作
    public  void  click(View v) {

        new Thread(){
            @Override
            public void run() {

                //handler.sendEmptyMessage(LOADING_START);
                try {
                    Thread.sleep();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

               // Message msg = Message.obtain();      //第一种方式
                Message msg = handler.obtainMessage();  //第二种方式
                //向msg中存取数据
                msg.what = LOADING_FINISH;
                msg.arg1 = ;
                msg.arg2 = ;
                msg.obj = System.currentTimeMillis();

                //调用sendMessage()方法   把Message的对象传进去
                handler.sendMessage(msg);

            }
        }.start();
    }
           
Handler handler = new Handler(){

           //此处接收所有有当前handler对象通过send方法发出的消息
           //参数代表接收到的消息对象
        @Override
        public void handleMessage(Message msg) {
         //通过msg对象的what属性取出当前接收到的消息的标识

            int a =msg.arg1;    //取值
            int b =msg.arg2;   //取值
            Long s = (Long) msg.obj;

            textView.setText(a+" " + b+" " +s);
            super.handleMessage(msg);
        }
    };
           
如果想要存储多个数据的话:采用Bundle 如下:
           
//模拟按钮  进行耗时操作
    public  void  click(View v) {

        new Thread(){
            @Override
            public void run() {

                //handler.sendEmptyMessage(LOADING_START);
                try {
                    Thread.sleep();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

               // Message msg = Message.obtain();      //第一种方式
                Message msg = handler.obtainMessage();  //第二种方式
                //向msg中存取数据
                msg.what = LOADING_FINISH;

                Bundle  bundle = new Bundle();
                bundle.putString("data", "dfasdfa");
                bundle.putBoolean("boo", true);
                msg.setData(bundle);

                //调用sendMessage()方法   把Message的对象传进去
                handler.sendMessage(msg);

            }
        }.start();
    }
           
Handler handler = new Handler(){

           //此处接收所有有当前handler对象通过send方法发出的消息
           //参数代表接收到的消息对象
        @Override
        public void handleMessage(Message msg) {
         //通过msg对象的what属性取出当前接收到的消息的标识

            if(msg.what == LOADING_FINISH) {

                Bundle data = msg.getData();
                textView.setText(data.getString("data")+" "+data.getBoolean("boo"));
                super.handleMessage(msg);
            }
        }
    };
           
好了,第一节的简单的handler的用法,先写到这哈。以上代码如有不妥指出,还望指出谢谢。。  
           

继续阅读