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