• Android handler学习笔记


    • 调用Message.obtain()从消息池中获得一个message对象,而不是直接new一个message对象,可以节省内存开销。也可以用handler.obtainMessage(),其实是一样的,obtainMessage()就是返回Message.obtain()
    • message.sendToTarget()跟handler.sendMessage()是一样的
    • 下面的方式可以拦截Message。
      private Handler handler=new Handler(new Callback(){
              public boolean handleMessage(Message msg){
                  //在Callback中可以拦截掉message
                  //这里返回true以后就不会再执行下面的那个handleMessage。
                  if(msg.what==1)return true;
                  return false;
              }
          }){
              public void handleMessage(Message msg){
                  //处理消息
              }
          };
    • Handler发送消息,加入MessageQueue队列。Looper接收Handler发过来的消息,轮询MessageQueue队列,然后回传给Handler。
    • Message绑定handler。可以用 
      Message msg=handler.obtainMessage();  msg.sendToTarget();
      Message msg=Message.obtain(handler);  msg.sendToTarget();
      Message msg=Message.obtain();   handler.sendMessage(msg);
      或者手动绑定,使用  msg.setTarget(handler);
    • HandlerThread自动包含Looper,不需要手动创建,用起来方便。
    • 因为主线程中默认包含了一个Looper,所以不需要再传入Looper。在子线程中使用Handler则需要传入一个thread的looper进去,而如果thread是handlerThread,可以直接用handlerThread.getLooper()拿到looper。如果是自己写的一个thread,在里面创建一个looper,因为不同线程处理,很可能报空指针错误。
    • 为普通线程创建Looper的方法如下:在线程run()方法当中先调用Looper.prepare()初始化Looper,然后再run()方法最后调用Looper.loop(),这样我们就在该线程当中创建好Looper。(注意:Looper.loop()方法默认是死循环)。用HandlerThread可以省事。
    • Handler会关联一个单独的线程和消息队列。
    • 只有在run中的东西才是运行在子线程中的。

    下面做了一个例子,handler例子:

    package com.ac.handlertest;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.HandlerThread;
    import android.os.Looper;
    import android.os.Message;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.TextView;
    
    public class MainActivity extends Activity implements OnClickListener {
        private Layout layout;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initLayout();
            initValue();
        }
    
        private void initLayout() {
            layout = new Layout();
            layout.helloText = (TextView) findViewById(R.id.helloText);
            layout.button1 = (Button) findViewById(R.id.button1);
            layout.button2 = (Button) findViewById(R.id.button2);
            layout.button3 = (Button) findViewById(R.id.button3);
            layout.button1.setOnClickListener(this);
            layout.button2.setOnClickListener(this);
            layout.button3.setOnClickListener(this);
        }
    
        private void initValue() {
            layout.helloText.setText("");
            layout.button1.setText("1.主线程的Handler");
            layout.button2.setText("2.普通子线程的Handler");
            layout.button3.setText("3.使用HandlerThread");
        }
    
        private class Layout {
            TextView helloText;
            Button button1;
            Button button2;
            Button button3;
        }
    
        // 1.主线程的Handler
        private void method_1() {
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    Log.i("msg", "" + Thread.currentThread());//主线程
                    layout.helloText.setText("因为主线程中默认包含了一个Looper,所以不需要再传入Looper。");
                }
            }, 1000);
        }
    
        // 2.普通子线程的Handler
        private void method_2() {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    Looper.prepare();
                    Handler handler = new Handler() {
                        public void handleMessage(Message msg) {
                            Log.i("msg", "" + Thread.currentThread());//子线程myThread1
                            runOnUiThread(new Runnable() {
                                public void run() {
                                    layout.helloText
                                            .setText("为普通线程创建Looper的方法如下:在线程run()方法当中先调用Looper.prepare()初始化Looper,然后再run()方法最后调用Looper.loop(),这样我们就在该线程当中创建好Looper。(注意:Looper.loop()方法默认是死循环)。");
                                }
                            });
                        };
                    };
                    try {
                        Thread.sleep(1000);
                        handler.sendEmptyMessage(0);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Looper.loop();
                }
            });
            thread.setName("myThread1");
            thread.start();
        }
    
        // 3.使用HandlerThread
        private void method_3() {
            HandlerThread handlerThread = new HandlerThread("myThread2");
            handlerThread.start();
            Handler handler = new Handler(handlerThread.getLooper()) {
                public void handleMessage(Message msg) {
                    Log.i("msg", "" + Thread.currentThread());//子线程myThread2
                    runOnUiThread(new Runnable() {
    
                        @Override
                        public void run() {
                            layout.helloText
                                    .setText("而handlerThread可以直接用handlerThread.getLooper()拿到looper,可以不用管looper,可以省事");
                        }
                    });
                }
            };
            handler.sendEmptyMessage(0);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.button1:
                method_1();
                break;
            case R.id.button2:
                method_2();
                break;
            case R.id.button3:
                method_3();
                break;
            default:
                break;
            }
        }
    }
    MainActivity.java

    完整demo:http://pan.baidu.com/s/1qWwTs3y

  • 相关阅读:
    new操作符
    delete和delete[] 的区别
    oracle查看编码以及修改编码
    C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast
    error:/usr/bin/ld:skipping incompatible ./libxxxx.so when searching for lxxxx
    shell环境变量以及set,env,export的区别
    malloc/free和new/delete的区别
    form表单提交回调函数
    jQuery ajax 跨域请求
    开博咯
  • 原文地址:https://www.cnblogs.com/chace/p/4338428.html
Copyright © 2020-2023  润新知