使用HandlerThread创建一个工作在新线程的Servic

2017-05-22  本文已影响44人  Bejamin

HandlerThread是Android API提供的一个便捷的线程类,使用它我们可以快速地创建一个带有Looper的线程,而这个Looper是和线程一对一绑定的。有了这个Looper之后,我们又可以生成工作在这个线程里面的Handler。

实现原理

在介绍原理之前,我们先用普通的Thread来创建一个Handler,过程大致如下:

Handler handler;
private void createMannualThreadWithHandler(){
    new Thread(){
        @Override
        public void run(){
            super.run();
            Looper.prepare();
            handler = new Handler(Looper.myLooper());
            Looper.loop();
        }
    }.start();
}

实现很简单,需要在目标线程中做如下配置

注意:
Looper.prepare()在一个线程中只能调用一次,否则会抛出异常;Looper.loop()方法是一个死循环,需要使用quit()/quitSafely()退出。

明白了上面的实现步骤,HandlerThread的实现也就简单了,源码如下:

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

Handler原理

理解Handler的原理,只需记住以下几点即可:

如何使用

HandlerThread使用起来很容易,首先下以后进行初始化。

private Handler handler;
private LightTaskManager(){
    HandlerThread workerThread = new HandlerThread("LightTaskThread");
    workerThread.start();
    handler = new Handler(workerThread.getLooper());
}

注意,上面的workerThread.start();必须要先执行。

至于如何使用HandlerThread来执行任务,主要是调用Handler的API。

下面给出使用HandlerThread创建一个工作在新线程的Service组件。

使用HandlerThread创建一个工作在新的线程的Service组件的代码框架如下:

public class LDMService extends Service{
    private HandlerThread ldmThread;
    private LDMHandler ldmHandler;
    
    final class LDMHandler extends Handler{
        public LDMHandler(Looper looper){
            // 将Handler和looper绑定
            super(looper);
        }
        
        @Override
        public void handleMessage(Message msg){
            // TODO:处理消息的应用逻辑
        }
    }
    
    @Override
    public void onCreate(){
        // Start up the thread running the service.  Note that we create a
        // separate thread because the service normally runs in the process's
        // main thread, which we don't want to block.  We also make it
        // background priority so CPU-intensive work will not disrupt our UI.
        ldmThread = new HandlerThread("LDM Service Thread", Process.THREAD_PRIORITY_BACKGROUND);
        ldmThread.start;
        ldmHandler = new LDMHandler(ldmThread.getLooper());
    }
    
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    @Override
    public void onDestroy(){
        ldmThread.quitSafely();
    }
}
上一篇下一篇

猜你喜欢

热点阅读