美文网首页
Handler的工作原理(一)Handler的使用

Handler的工作原理(一)Handler的使用

作者: 贝贝ovo | 来源:发表于2018-08-21 14:58 被阅读15次

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究竟是怎样完成切换线程执行任务的呢,下篇继续深入

相关文章

网友评论

      本文标题:Handler的工作原理(一)Handler的使用

      本文链接:https://www.haomeiwen.com/subject/totjiftx.html