HandlerThread小讲解

    接触过Android项目开发的小伙伴应该都知道,Handler在Android中占有举足轻重的地位。因为一个项目的开发,多线程的运用是必不可少的,但是如果在异步线程完成某些耗时操作后,想对UI进行操作时,由于Android设计不允许在子线程更新UI,那怎么办?
    利用Handler,一个Message发送过去,就可以轻轻松松完成这个操作啦。
    对于Handler的应用,大多数场景都是这样。但是假如你想要在Handler处理Message方法中实现异步的操作,又该怎么办呢?有不懂事的小伙伴可能会说,直接使用Handler.post(new Runnable(){});就行啦,如果还有这个想法的,那建议小伙伴还是回去加深一下Handler、Thread、Runnable的理解。当然,还有的小伙伴会说,在Handler的handlerMessage()方法中new一个新的Thread,不就完事了嘛。的确如此,new一个新的Thread来实现异步操作的确没有问题,但假如Handler发送的Message之前有着必要的先后执行顺序,如果每接受到一个Message,就开一个新的线程去操作,那这个应用的线程管理,将会无比复杂,稍不留神,可能就会出现各种问题。
针对以上这些情况,你们的救世主来啦,它就是–HandlerThread!!!
对于HandlerThread,它在API中的解释是这样的:

    Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.

     HandlerThread是一个很方便的类,它用于启动一个拥有Looper的新线程,而这个Looper适用于创建Handler对象。但是它有一个使用条件,那就是必须要先执行start()方法

    private HandlerThread ht;
    private Handler mThreadHandler;
    private Activity mActivity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mActivity = this;

        //init views
        mThreadNameView = findViewById(R.id.thread_name);
        mUiHandlerBtn = findViewById(R.id.ui_handler_btn);
        mHandlerThreadBtn = findViewById(R.id.thread_handler_btn);
        mUiHandlerBtn.setOnClickListener(this);
        mHandlerThreadBtn.setOnClickListener(this);

        //init Handler
        ht = new HandlerThread("Handler Thread");
        ht.start();
        mThreadHandler = new Handler(ht.getLooper());
    }
    @SuppressLint("HandlerLeak")
    private Handler mUIHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Log.i(TAG, "mUIHandler: current thread name: " + Thread.currentThread().getName());
            Log.i(TAG, "mUIHandler: current thread is main thread ? "
                    + (Thread.currentThread().getId() == Looper.getMainLooper().getThread().getId()));
            showCurrentThreadName(Thread.currentThread());
        }
    };

    private void showCurrentThreadName(final Thread myThread) {
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mThreadNameView.setText(myThread.getName());
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.ui_handler_btn:
                mUIHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        Log.i(TAG, "mUIHandler run on new Runnable, current thread is "
                                + Thread.currentThread().getName());
                    }
                });
                mUIHandler.sendEmptyMessage(0);
                break;
            case R.id.thread_handler_btn:
                mThreadHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        showCurrentThreadName(Thread.currentThread());
                    }
                });
                break;
        }
    }

    通过执行可以发现,在主线程创建的UIHandler,在handlerMessage或者是new Runnable(){},均是在主线程执行的,而通过HandlerThread的Looper创建的ThreadHandler,则是运行在“Handler Thread”此线程中。

至此,简单的HandlerThread讲解以及运用,就基本完成了。

在此附上本人的Demo链接 https://gitee.com/meinkonone/HanderThread

 

    

    原文作者:移动开发
    原文地址: https://my.oschina.net/mkonone/blog/1809618
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞