Learn HandlerThread

HandlerThread is a class that extends Thread. It means that it is no different from the call of the ordinary Thread class, and it still needs to be called start(). Please add a picture description
As shown in the figure above, the extended HandlerThread class has a Looper and a Handler.
For knowledge about this piece, please refer to "Knowledge we should know about Handler"

The run method of HandlerThread:

    @Override
    public void run() {
    
    
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
    
    
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

Calling start()is to start a thread, and this thread first creates a Looper.

  • Looper.prepare();It is to prepare a Looper for the current thread,
  • Looper.myLooper();It is to retrieve the created Looper.
  • onLooperPrepared();If you want to set something before running the message queue, you can override this method
  • Looper.loop();Run the message queue in this thread

To stop the started Looper, you must call the Looper's quit() method. HandlerThread has such a method:

public boolean quit() {
    
    
        Looper looper = getLooper();
        if (looper != null) {
    
    
            looper.quit();
            return true;
        }
        return false;
    }

  • getLooper();Get the Looper in the HandleThread instance
  • looper.quit();End the Looper of the current thread

Having said so much, combined with my last article "Knowledge we should know about Handler", we know that HandlerThread provides a convenience for creating Looper in threads to handle our tasks.

Although there is a getThreadHandler() method in the HandlerThread class to get the Handler, it is impossible for you to call it . This method is @hideannotated with

/**
     * @return a shared {@link Handler} associated with this thread
     * @hide
     */
    @NonNull
    public Handler getThreadHandler() {
    
    
        if (mHandler == null) {
    
    
            mHandler = new Handler(getLooper());
        }
        return mHandler;
    }

@hide It actually controls the android.jar package

Let's talk about that in another article @hide. Let's continue to talk about HandlerThread.

So we can only create a Handler instance to bind the Looper of the HandlerThread thread:

In this way, our tasks can be placed in other threads for execution. Let's have an example!

 val handlerThread = HandlerThread("Hello")

        handlerThread.start() // 要在绑定Handler前调用,否则Looper就没有创建好

        val handler = object: Handler(handlerThread.looper) {
    
    
            override fun handleMessage(msg: Message) {
    
    
                println("Hello world8888888888888888888")
            }
        }

        handler.sendMessage(Message.obtain())

        handler.sendMessage(Message.obtain())

        Thread.sleep(3000)
        handlerThread.quit()// 不再使用的话,要记得停到Looper
        // 收到error java.lang.IllegalStateException: Handler ... 
        // sending message to a Handler on a dead thread
        handler.sendMessage(Message.obtain()) 

For example, we create a thread ourselves and let it start a Looper to help us do things:

var mLooper: Looper? = null
// 启动一个线程,并为当前线程
Thread{
    
    
    Looper.prepare()
    synchronized(this) {
    
    
        mLooper = Looper.myLooper()
    }
    Looper.loop()
}.start()

Thread.sleep(3000) // Looper创建是要些时间的,所以我们等一下它。

val myHandler = object: Handler(mLooper!!){
    
    
     override fun handleMessage(msg: Message) {
    
    
        println("Hey world @@@@@@@@@")
     }
 }

myHandler.sendMessage(Message.obtain())

A more elegant version, java's will be simpler:

 var mLooper: Looper? = null
        val lock = ReentrantLock()
        val condition = lock.newCondition()
        Thread{
    
    
            Looper.prepare()
            try {
    
    
                lock.lock()
                mLooper = Looper.myLooper()
                condition.signalAll()
            }catch (e: Exception){
    
    

            }finally {
    
    
                lock.unlock()
            }

            Looper.loop()
        }.start()

        try {
    
    
            lock.lock()
            if (mLooper == null) condition.await()
        }catch (e: Exception){
    
    
            e.printStackTrace()
        }finally {
    
    
            lock.unlock()
        }

        val myHandler = object: Handler(mLooper!!){
    
    
            override fun handleMessage(msg: Message) {
    
    
                println("Hey world @@@@@@@@@")
            }
        }

        myHandler.sendMessage(Message.obtain())

That's all, thank you for coming!

Guess you like

Origin blog.csdn.net/weixin_40763897/article/details/128978704