理解android IntentService的实现

首先,IntentService的启动与Service一样,直接Context.startService即可。

为什么会使用IntentService ?

1: intentService的生命周期不需要我们自己去管理,使用完自动销毁,具体为什么自动销毁看源码分析。

2: 耗时操作不需要跟service一样,需要在onStartCommand另起线程,系统默认开启一个新的线程去管理(HandlerThread)

源码分析:

当启动服务,调用Context.startService方法时,默认启动IntentService.OnCreate()方法:

@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);
}
可以看出当启动服务时,会创建一个HandlerThread,那么这个HandlerThread有什么作用,继续看

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

当thread.start()方法执行时,会调用HandlerThread的run方法,run方法里面目的是创建一个Looper。
使用这个looper去创建一个Handler,具体为什么可以查找资料Handler与looper之间关系的相关资料。
但是,为什么在调用Looper.myLooper()的 时候要加锁呢???
请看
 
mServiceLooper = thread.getLooper(); 执行到这句的时候,获取当前looper,
/**
 * This method returns the Looper associated with this thread. If this thread not been started
 * or for any reason is isAlive() returns false, this method will return null. If this thread 
 * has been started, this method will block until the looper has been initialized.  
 * @return The looper.
 */
public Looper getLooper() {
    if (!isAlive()) {
        return null;
    }
    
    // If the thread has been started, wait until the looper has been created.
    synchronized (this) {
        while (isAlive() && mLooper == null) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
    }
    return mLooper;
}

一看一目了然,因为在创建looper的时候,是在子线程创建的,但是在执行
 
 
 
mServiceLooper = thread.getLooper()这个的时候是在另一个线程,所以就有可能执行
这句话的时候looper还没创建成功,就执行到wait()方法,等待looper创建成功
,调用
 
notifyAll();通知可以获取looper对象了。
这句是IntentService的oncreate方法。那么执行完之后,继续service的生命周期方法:
@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);
}
发现这个方法里面用了handler发送消息,那么就来找找handler接收到这个消息之后做了什么:
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方法,这个是intentService需要重写,实现自己逻辑的方法。
然后调用了stopSelf方法停止这个service。这就是为什么intentService不需要我们去调用stopService了。

但是为什么说onHandleIntent这个方法是在子线程做操作的呢?

继续看,我们这个handler的创建是获取到子线程的looper,创建looper的时候我们会new 一个ThreadLocal

这个ThreadLocal是一个泛型,会把looper对象保存在ThreadLocal里面,其他的原因就跟创建
Handler是一个意思了。可以查看相关文档

所以说这个handler里面的操作都是在这个looper所在线程里面去操作的,也就是说在子线程里面去操作。





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值