HandlerThread + IntentService

作者: 糖葫芦_倩倩 | 来源:发表于2018-09-29 15:29 被阅读11次

1. 初始 HandlerThread

/**
内部创建了一个线程和一个looper. 这个looper可以用来创建 Handler.
 切记一定要调用start()方法
 * 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.
 */
public class HandlerThread extends Thread {
      Looper mLooper;
      .....
}

run 方法:

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

handlerThread 和普通的 Thread 有显著的不同,它的 run 方法不是执行任务的,而是创建了 Looper ,然后调用 Looper.loop 开启了死循环。
外界需要通过Handler 的消息方式来通知 HandlerThread 执行任务。一般配合IntentService 使用。

2.IntentService

  • 定义
/**
 * IntentService is a base class for {@link Service}s that handle asynchronous
 * requests (expressed as {@link Intent}s) on demand.  Clients send requests
 * through {@link android.content.Context#startService(Intent)} calls; the
 * service is started as needed, handles each Intent in turn using a worker
 * thread, and stops itself when it runs out of work.
 *
 * <p>This "work queue processor" pattern is commonly used to offload tasks
 * from an application's main thread.  The IntentService class exists to
 * simplify this pattern and take care of the mechanics.  To use it, extend
 * IntentService and implement {@link #onHandleIntent(Intent)}.  IntentService
 * will receive the Intents, launch a worker thread, and stop the service as
 * appropriate.
 *
 * <p>All requests are handled on a single worker thread -- they may take as
 * long as necessary (and will not block the application's main loop), but
 * only one request will be processed at a time.
 *
 * <div class="special reference">
 * <h3>Developer Guides</h3>
 * <p>For a detailed discussion about how to create services, read the
 * <a href="{@docRoot}guide/components/services.html">Services</a> developer
 * guide.</p>
 * </div>
 *
 * @see android.os.AsyncTask
 */
public abstract class IntentService extends Service {
  .....
    @Override
    public void onCreate() {
        // TODO: It would be nice to have an option to hold a partial wakelock
        // during processing, and to have a static startService(Context, Intent)
        // method that would launch the service & hand off a wakelock.

        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }
}

是一种特殊的 service ,继承于 service, 并且是一个抽象类。它封装了 HanlerThreadHandler.

通过

创建一个线程,并调用start 方法,run方法执行,里面是一个死循环,我们之前说过
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

利用thread中的looper 构建了 ServiceHandler
 mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);

服务一旦启动之后,首先调用 onCreate 刚才我们已经看了,其次就是onStartCommand ,接下来我们看下 onStartCommand 方法:

 @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

onStart 方法:

@Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

这里不错有我们在之前 onCreate 中创建的 mServiceHandler ,将startId, intent 通过 sendMessage 发送出去了。看下 mServiceHandlerhandleMessage 方法:

private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
    }

最终调用onHandleIntent 方法,stopSelf(startId)单个任务执行完毕尝试关闭服务 ,onHandleIntent 抽象方法,前面extend IntentService 需要实现 onHandleIntent 方法,处理不同的Intent 任务,所有任务完成后自动 onDestroy.

当单个任务执行完毕之后不会立即调用onDestroy,虽然每次都调用stopSelf(startId)
其中startId 每调用一次 startService 这个 startId+1

public final void stopSelf(int startId) {
        if (mActivityManager == null) {
            return;
        }
        try {
            mActivityManager.stopServiceToken(
                    new ComponentName(this, mClassName), mToken, startId);
        } catch (RemoteException ex) {
        }
    }

ActivityManagerService

@Override
    public boolean stopServiceToken(ComponentName className, IBinder token,
            int startId) {
        synchronized(this) {
            return mServices.stopServiceTokenLocked(className, token, startId);
        }
    }
boolean stopServiceTokenLocked(ComponentName className, IBinder token,
            int startId) {

.....
    
      if (r.getLastStartId() != startId) {
                      return false;
       }
      这个lastStartId 会跟随着每次startService +1,这里能看出来:
      public int makeNextStartId() {
              lastStartId++;
              if (lastStartId < 1) {
                lastStartId = 1;
          }
            return lastStartId;
    }

}

oval

相关文章

网友评论

    本文标题:HandlerThread + IntentService

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