IntentService解析

IntentService是一个专门用来处理异步线程的一个服务,它内部创建了一个消息队列以及一个Handler对象,其它组件将Intent发送过来之后,IntentService会将这个Intent通过消息队列发送到工作线程,所以,我们可以放心大胆的在IntentService内部做耗时操作,而不必单独开启线程。

好,大概描述了下,我们看一下它的实现方式:

package android.app;

import android.annotation.WorkerThread;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;

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

	...
    public IntentService(String name) {
        super();
        mName = name;
    }

	...
    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

    @Override
    public void onCreate() {

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

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

	...
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

	...
    @WorkerThread
    protected abstract void onHandleIntent(Intent intent);
}

将注释代码删除掉之后,真正的实现代码很少,现在将对这些代码一一说明,首先是onCreate方法:

onCreate方法主要做了以下事情:

创建HandlerThread线程并启动,使用HandlerThread对象所创建的Looper对象初始化ServiceHandler对象,这样,就可以通过ServiceHandler对象HandlerThread中的消息队列发送数据了,我们看看他们之间是如何实现的,首先是HandlerThread:

...
package android.os;

...
public class HandlerThread extends Thread {
    int mPriority;
    int mTid = -1;
    Looper mLooper;

    public HandlerThread(String name) {
        super(name);
        mPriority = Process.THREAD_PRIORITY_DEFAULT;
    }
    
    ...
    public HandlerThread(String name, int priority) {
        super(name);
        mPriority = priority;
    }
    
    ...
    protected void onLooperPrepared() {
    }

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

    ...
    public boolean quit() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quit();
            return true;
        }
        return false;
    }

    ...
    public boolean quitSafely() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quitSafely();
            return true;
        }
        return false;
    }

    ...
    public int getThreadId() {
        return mTid;
    }
}

这个中的代码也不多,我们看主要的run方法:

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

run方法主要做了以下事情:

调用Looper.prepare();在当前线程中初始化一个Looper消息循环对象,并初始化了一个消息队列,拿到这个线程的Looper对象,然后开启消息循环访问模式。

接着回到IntentService的onCreate方法中,使用刚才的工作线程中的Looper对象来初始化ServiceHandler,使mServiceHandler对象向这个线程的Looper中发送消息。


准备工作做好之后,接下来的逻辑就简单了,其它组件通过startService方法,将Intent传递到这个服务中,会调用onStartCommand方法,onStartCommand调用onStart方法,而onStart方法会将接收到的Intent对象作为被传送的消息实体通过ServiceHandler发送到工作线程,然后我们如果使用的话,直接重写onHandleIntent就可以,onHandleIntent收到对象的时候已经处在工作线程当中。

我们在onHandleIntent方法中处理完毕任务之后,不必手动去调用stopSelf去停止服务,IntentService已经帮我们做了这样的处理。说到这里,可能你会有疑问,如果我在很短的时间内发送了多个请求,那么第一个请求处理完毕那服务不就终止了吗,后面的怎么处理呢,对于这个问题,需要详细了解一下stopSelf的说明:

如果我们现在工作在默认模式,同一时间只有一个Intent会被处理,如果在当前这个任务处理结束之前还有一个Intent请求过来的话,那它就不会被终止,它的原因与stopSelf有关系,stopSelf会判断终止的startId是否是最后发送过来的startId,所以,疑问解决了。


到这里基本的解释就说完了,有疑问欢迎留言。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值