zoukankan      html  css  js  c++  java
  • 【Android】HandlerThread原理分析

    个人博客:
    http://www.milovetingting.cn

    HandlerThread是一个内部拥有Handler和Looper的特殊Thread,可以方便地在子线程中处理消息。

    简单使用

    HandlerThread的使用比较简单。

    mHandlerThread = new HandlerThread(THREAD_NAME);
    mHandlerThread.start();
    

    首先,实例化一个HandlerThread,然后调用start()方法。在start()方法中,会调用run()方法:

    @Override
    public void run() {
        mTid = Process.myTid();
    	//实例化looper对象
        Looper.prepare();
        synchronized (this) {
    		//获取looper对象
            mLooper = Looper.myLooper();
    		//通知其它线程
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
    	//开启循环
        Looper.loop();
        mTid = -1;
    }
    

    然后,定义处理子线程消息的Handler:

    mThreadLooper = mHandlerThread.getLooper();
    
    mThreadHandler = new Handler(mThreadLooper, new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                switch (msg.what) {
                    case MSG_THREAD_UPDATE:
                        //在子线程中执行耗时任务
                        SystemClock.sleep(3000);
                        mMainHandler.sendEmptyMessage(MSG_MAIN_UPDATE);
                        break;
                    default:
                        break;
                }
                return false;
            }
        });
    

    在HandlerThread.getLooper()方法中:

    public Looper getLooper() {
        if (!isAlive()) {
            return null;
        }
        
        // If the thread has been started, wait until the looper has been created.
        synchronized (this) {
            while (isAlive() && mLooper == null) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }
    

    在getLooper()方法中,由于子线程可能还没有准备好looper,因此,会调用wait()方法等待,如果子线程looper已经准备好了,则会通过notifyAll()来唤醒。

    在子线程中可以执行耗时的操作,执行完成后,可以通过在UI线程的Handler发送消息去通知UI变更。

    mMainHandler.sendEmptyMessage(MSG_MAIN_UPDATE);
    

    UI线程的Handler:

    static class MainHandler extends Handler {
    
    	//为防止内存泄漏,引入WeakReference
        private WeakReference<Activity> mWeakReference;
    
        public MainHandler(Activity activity) {
            mWeakReference = new WeakReference<>(activity);
        }
    
        @Override
        public void handleMessage(Message msg) {
            MainActivity activity = (MainActivity) mWeakReference.get();
            if (activity != null) {
                switch (msg.what) {
                    case MSG_MAIN_UPDATE:
                        activity.updateInfo();
                        break;
                    default:
                        break;
                }
            }
    
        }
    }
    

    为防止内存泄漏,引入WeakReference。在onDestory()方法中,移除所有消息:

    mMainHandler.removeCallbacksAndMessages(null);
    
    mThreadLooper.quit();
    

    源码地址:https://github.com/milovetingting/Samples/tree/master/HandlerThread

  • 相关阅读:
    I
    H
    G
    F
    E
    论js里面的for循环
    js常见问题之为什么点击弹出的i总是最后一个
    array类型的方法
    string类型的方法
    for in在对象和数组中的应用
  • 原文地址:https://www.cnblogs.com/milovetingting/p/10649651.html
Copyright © 2011-2022 走看看