Service和IntentService的区别2

上一篇Service 和 IntentService 的区别对 IntentServcie 有了一个初步的了解。今天来结合 IntentService 的源码具体分析一下 IntentService 的内部实现原理。

先贴一下 IntentService 的源码。

IntentService 源码

public abstract class IntentService extends Service {
  private volatile Looper mServiceLooper;
  private volatile ServiceHandler mServiceHandler;
  private String mName;
  private boolean mRedelivery;

  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);
    }
}

  /**
   * Creates an IntentService.  Invoked by your subclass's constructor.
   *
   * @param name Used to name the worker thread, important only for debugging.
   */
  public IntentService(String name) {
    super();
    mName = name;
  }

  /**
   * Sets intent redelivery preferences.  Usually called from the constructor
   * with your preferred semantics.
   *
   * <p>If enabled is true,
   * {@link #onStartCommand(Intent, int, int)} will return
   * {@link Service#START_REDELIVER_INTENT}, so if this process dies before
   * {@link #onHandleIntent(Intent)} returns, the process will be restarted
   * and the intent redelivered.  If multiple Intents have been sent, only
   * the most recent one is guaranteed to be redelivered.
   *
   * <p>If enabled is false (the default),
   * {@link #onStartCommand(Intent, int, int)} will return
   * {@link Service#START_NOT_STICKY}, and if the process dies, the Intent
   * dies along with it.
   */
  public void setIntentRedelivery(boolean enabled) {
    mRedelivery = enabled;
  }

  @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);
  }

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

  /**
   * You should not override this method for your IntentService. Instead,
   * override {@link #onHandleIntent}, which the system calls when the IntentService
   * receives a start request.
   * @see android.app.Service#onStartCommand
   */
  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    onStart(intent, startId);
    return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
  }

  @Override
  public void onDestroy() {
    mServiceLooper.quit();
  }

  /**
   * Unless you provide binding for your service, you don't need to implement this
   * method, because the default implementation returns null. 
   * @see android.app.Service#onBind
   */
  @Override
  public IBinder onBind(Intent intent) {
    return null;
  }

  /**
   * This method is invoked on the worker thread with a request to process.
   * Only one Intent is processed at a time, but the processing happens on a
   * worker thread that runs independently from other application logic.
   * So, if this code takes a long time, it will hold up other requests to
   * the same IntentService, but it will not hold up anything else.
   * When all requests have been handled, the IntentService stops itself,
   * so you should not call {@link #stopSelf}.
   *
   * @param intent The value passed to {@link
   *               android.content.Context#startService(Intent)}.
   */
  @WorkerThread
  protected abstract void onHandleIntent(Intent intent);
}

IntentService 的执行过程

首先,来按 Service 的生命周期过一下代码。

  1. oncreate: 在这里面首先启动了一个 HandlerThread 线程,然后获取它的 Looper,再用这个 Looper 来初始化 Handler。
  2. onStartCommand: 里面调用了onstart(Intent intent, int startId)。传入了一个 Intent 和一个 int 值。
  3. onStart:从消息队列中获取一个消息。把传入的 startId 和 intent 赋值给Message。然后用 sendMessage()发送 msg。
  4. 然后 Handler 收到消息后处理,调用 onHandleIntent(),传入 intent 值,然后 stopSelf(msg.arg1)。

为了看看 IntentService 的线程情况。
我们在自定义的 IntentService 打印各个周期当前所在的线程名。

public class MyIntentService extends IntentService {
  String TAG = "MyIntentService2";
  public MyIntentService2() {
    super("luwenjie2");
}

  @Override
  public void onCreate() {
    Logger.d(TAG,"当前线程-->"+Thread.currentThread().getName());
    super.onCreate();
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    Logger.d(TAG,"当前线程-->"+Thread.currentThread().getName());
    return super.onStartCommand(intent, flags, startId);
  }

  @Override
  public void onStart(Intent intent, int startId) {
    Logger.d(TAG,"当前线程-->"+Thread.currentThread().getName());
    super.onStart(intent, startId);
  }

  @Override
  public IBinder onBind(Intent intent) {
    Logger.d(TAG,"当前线程-->"+Thread.currentThread().getName());
    return super.onBind(intent);
}

  @Override
  public void setIntentRedelivery(boolean enabled) {
    super.setIntentRedelivery(enabled);
    Logger.d(TAG,"当前线程-->"+Thread.currentThread().getName());
  }

  @Override
  protected void onHandleIntent(Intent intent) {
    Logger.d(TAG,"当前线程-->"+Thread.currentThread().getName());
}

结果只有执行 onHandleIntent 的时候在 IntentService[luwenjie2] 线程,其他都是在 main 线程。

分析

它把发来的 Intent 发到新线程中去处理。对于异步的请求,因为用了 Handler 消息队列,所以他会先处理完第一个再处理第二个。
最后他调用 stopSelf 函数终止了自己,所以我们不需要手动终止它。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值