• Android的消息机制Handler


    android的消息机制——Handler:Handler是一个Android SDK 提供给开发者方便进行异步消息处理的类。

    一.为什么用handler
    1.消息机制:不同线程之间的通信。那么推出来android的消息机制可以用handler机制来概况.
    2.那么android为什么会用到handler机制:避免ANR.
    3.避免ANR的方法就是:子线程执行耗时操作,通过handler机制完成UI在主线程的更新.
    4.那么为什么子线程不能执行UI:因为UI控件不是线程安全的,那么多线并发对UI进行操作会达到不可预期的结果.
    5.那么UI控件为什么不设计为线程安全的:因为设计为线程安全的,首先UI性能低效,其次有种杀鸡焉用牛刀的感觉,UI设计是秉承着简单有效的原则,那么有悖于设计.

    二,handler中几个关键的类(Handler、Looper、MessageQueue、Message、ThreadLocal):

     1.从使用角度来说用handler就是:建立handler重写handlermsg方法对消息进行处理,通过线程sendmsg.
     2.Handler特性:
              a.Android里没有全局Message Queue消息队列,每个Activity都有一个独立的消息队列且采用先进先出的原则.不同APK不能通过handle进行消息传递.
       b.每个handler实例都会绑定到创建它的线程中.
       c.handler发送消息到Message Queue中,每个massage发送到消息队列中采用先进先出原则.发送消息采用异步方式不会阻塞线程,而接受消息采用同步方式会阻塞线程,即handler处理完一个mesage消息对象后才会接着去取
          下一个消息进行处理.
        
     3.那么对于几个经常用的类作用如下:
            Handler负责发送和处理消息
            Looper消息泵,将循环取消息将取到的消息交给handler进行处理.没有消息的时候将会处于阻塞状态.
            MessageQueue消息队列,负责存取消息。
            Message具体发送的消息。
            ThreadLocal它主要用于做线程间的数据隔离用的,这里它在每个线程中存放各自对应的Looper。

    三.常用handler消息处理例子讲解.
      根据常用的几种handler消息传递使用方式进行讲解.
      首先创建一个activity,在activity实例3个button,分别处理常用的几种类型的handler.

      1.主线程建立handler自用.2.子线程通过Looper.getMainLooper()获取父类的looper建立handler.3.将主线程的handler传递给子线程进行通信.

    public class MainActivity extends Activity implements OnClickListener{
        Button mHandlerButton1 = null;
        Button mHandlerButton2 = null;
        Button mHandlerButton3 = null;
        Handler myHandler;
        Message msg;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main1);
            mHandlerButton1 = (Button)findViewById(R.id.handler_button1);
            mHandlerButton1.setOnClickListener(this);
            mHandlerButton2 = (Button)findViewById(R.id.handler_button2);
            mHandlerButton2.setOnClickListener(this);
            mHandlerButton3 = (Button)findViewById(R.id.handler_button3);
            mHandlerButton3.setOnClickListener(this);
        }
    
        public void onClick(View v){
            if(v == mHandlerButton1){
                myHandler = new MyHandler();
                msg = myHandler.obtainMessage(1,"threadmain handler");
                msg.sendToTarget();
            }else if(v == mHandlerButton2){
                InnerThread innerthread = new InnerThread();
                innerthread.start();
            }else if(v == mHandlerButton3){
                myHandler = new MyHandler();
                MyThread mythread = new MyThread(myHandler);
                mythread.start();
            }
        }
        private class InnerThread extends Thread{
            @Override
            public void run(){
                //myHandler = new MyHandler();//仅能在主线程内采用不带Looper对象创建Hanler对象.此处如果这么用会抛异常
                //myHandler = new MyHandler(Looper.myLooper());//Looper.myLooper获取looper为null
                myHandler = new MyHandler(Looper.getMainLooper());//获取父类的looper可以成功创建handler并发送消息
                msg = myHandler.obtainMessage(2,"InnerThread handler");
                msg.sendToTarget();
            }
        }
        private class MyThread extends Thread{
            private Handler innerHandler; 
            public MyThread(Handler handler){
                this.innerHandler = handler;//通过构造器获取主线程的handler并发送给主线程.
            }
            @Override
            public void run(){
                msg = innerHandler.obtainMessage(3,"MyThread handler");
                msg.sendToTarget();
            }
        }
        public class MyHandler extends Handler{
            public MyHandler(Looper myLooper){
                super(myLooper);
            }
            public MyHandler(){}//
            @Override
            public void handleMessage(Message msg){
                switch(msg.what){
                case 1:
                    Log.d("HandlerMessage","this handler is in main thread");
                    break;
                case 2:
                    Log.d("HandlerMessage","this handler is in InnerThread");
                    break;
                case 3:
                    Log.d("HandlerMessage","this handler is in MyThread");
                    break;
                    default:
                     break;
                }
            }
        }
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
      <Button
          android:id="@+id/handler_button1"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@string/handlerbutton1"/>
      <Button
          android:id ="@+id/handler_button2"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@string/handlerbutton2"/>
       <Button
          android:id ="@+id/handler_button3"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@string/handlerbutton3"/>
          
    
    </LinearLayout>

    从handler特质来看,handler主要异步处理较费时的操作,优先将界面返回给客户,处理完成后进行ui的更新.

  • 相关阅读:
    隐私保护政策
    童真儿童简笔画
    方块十字消
    iOS 判断一断代码的执行时间(从网上看的,自己实现一下)
    iOS BLOCK回调:(妖妖随笔)
    typedef struct
    #define和预处理指令
    UIActivityIndicatorView
    Expected a type 的错误
    iOS 本地化字符串—(妖妖随笔)
  • 原文地址:https://www.cnblogs.com/syyh2006/p/9172168.html
Copyright © 2020-2023  润新知