Handler的运行机制也是Android主要的消息机制;
Handler的主要作用是将一个任务切换到某个指定的线程中去执行;

Q:为什么Android要提供这种功能呢?
AAndroid规定访问UI只能在主线程中进行,但Android又不建议在主线程中进行耗时操作。这时Handler就排上用场啦,在子线程中进行拉取工作,用Handler切换一下UI访问的执行线程来处理UI操作

好,我们先学会使用,再深入源码理解原理,
常规使用有两种: 一种post(),一种sendMessage()

post方法

public class MainActivity extends AppCompatActivity {    private static final String TAG = MainActivity.class.getSimpleName();    // post方法 handler的创建    Handler handler = new Handler();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        new Thread(new Runnable() {            @Override            public void run() {                /*post方法解决UI更新,直接在runnable里面完成更新操作,                这个任务会被添加到handler所在线程的消息队列中,即主线程的消息队列中*/                handler.post(new Runnable() {                    @Override                    public void run() {                       String result = "更新UI";                        Log.d(TAG, "接收到的消息是: " + result);                    }                });            }        }).start();    }}

sendMessage方法

public class MainActivity extends AppCompatActivity {    private static final String TAG = MainActivity.class.getSimpleName();    // sendMessage方法 handler的创建    private static Handler sHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            /*sendMessage方法更新UI的操作必须在handler的handleMessage回调中完成*/            switch (msg.what) {                case 1:                    Log.d(TAG, "接收到的消息是: " + msg.obj);                    break;                default:            }        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        new Thread(new Runnable() {            @Override            public void run() {                /*sendMessage方法解决UI更新发送消息给handler(主线程中的handler)*/                Message msg = new Message();                msg.what = 1;                msg.obj = "更新UI";                sHandler.sendMessage(msg);            }        }).start();    }}

两个方法都是在子线中获取到信息后在主线程中访问UI,分析下这两种方法的区别,上源码分析
post方法源码

  /**     * Causes the Runnable r to be added to the message queue.     *  把任务r 添加到消息队列中     */    public final boolean post(Runnable r) {        return sendMessageDelayed(getPostMessage(r), 0);//注意这里    }    public final boolean sendMessageDelayed(Message msg, long delayMillis) {        if (delayMillis < 0) {            delayMillis = 0;        }        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);    }    private static Message getPostMessage(Runnable r) {        Message m = Message.obtain();        m.callback = r;        return m;    }

sendMessage方法源码

   public final boolean sendMessage(Message msg) {        return sendMessageDelayed(msg, 0);//注意这里    }

可以看出这两个方法最终调用的都是同一个方法sendMessageDelayed(),所以他们的本质都是一样的,只是用法的区别。post方法把任务Runable r包装成了message。那sendMessageDelayed()做了什么事,Handler究竟是怎样完成切换线程执行任务的呢,下篇继续深入

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initHandler();        initHandler2();    }    /**     * 初始化Handler 主线程     */    private void initHandler() {         final Handler handler = new Handler(){             @Override             public void handleMessage(Message msg) {                 if(msg.arg1==1) {                     Toast.makeText(MainActivity.this, "handleMessage", Toast.LENGTH_SHORT).show();                 }                 Log.e("handler",Thread.currentThread().getName());                 super.handleMessage(msg);             }         };         new Thread(new Runnable() {             @Override             public void run() {                 Log.e("handler==",Thread.currentThread().getName());                 Message message = handler.obtainMessage();                 message.arg1 = 1;                 handler.sendMessage(message);             }         }).start();    }    /**     * 初始化Handler 子线程     */    private void initHandler2() {        new Thread(new Runnable() {            @Override            public void run() {                Log.e("handler2",Thread.currentThread().getName());                Looper.prepare();                Handler handler = new Handler() {//                    Handler handler = new Handler(Looper.getMainLooper()) {                    @Override                    public void handleMessage(Message msg) {                        if (msg.arg1 == 1) {                            Toast.makeText(MainActivity.this, "handleMessage", Toast.LENGTH_SHORT).show();                        }                        Log.e("handler2==",Thread.currentThread().getName());                        super.handleMessage(msg);                    }                };                Message message = handler.obtainMessage();                message.arg1 = 1;                handler.sendMessage(message);                Looper.loop();            }        }).start();    }}

更多相关文章

  1. Android退出应用的方法总结
  2. Android–多线程之Handler下载图片源码
  3. android基础知识02——线程安全3:Message,MessageQueue,Handler,Loop
  4. Android内存泄漏的轻松解决方法
  5. Android中播放声音的两种方法
  6. Android Activity之间跳转出现短暂黑屏的处理方法和intent.setFl
  7. 基于xml类型的压缩数据流的android获取天气的方法

随机推荐

  1. android与H5混合开发
  2. [置顶] Unity与Android交互-android的安
  3. 浙大网新仿真实训android培训好不好
  4. simpleLib - android 快速开发框架
  5. Android系统移植与调试之------->Android
  6. 学生怎么入门Android?这四点很重要!
  7. 献给android原生应用层开发初学者技术架
  8. Android通过注解初始化View
  9. Android中Intent的setData,setType和setD
  10. Android(安卓)NDK编程入门