美文网首页
Android IntentService 源码解析

Android IntentService 源码解析

作者: SunnyGL | 来源:发表于2020-12-08 11:23 被阅读0次

IntentService 是一种特殊的 Service,它继承了 Service 并且它是一个抽象类,因此必须创建它的子类才能使用 IntentService。IntentService 可用于执行后台耗时的任务,当任务执行结束后它会自动停止,同时由于 IntentService 是服务的原因,这导致它的优先级比单纯的线程要高很多,所以 IntentService 比较适合执行一些高优先级的后台任务,因为它优先级高不容易被系统杀死。

一、源码剖析
1. IntentService 是 Service 的子类,所以 IntentService 也是一个服务
public abstract class IntentService extends Service {
    ······
}
2. IntentService 内部会创建 HandlerThread 和 Handler 实例,并将 HandlerThread 内的 Looper 作为 Handler 的 Looper,服务销毁时退出 Looper
@Override
public void onCreate() {
    super.onCreate();
    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
    thread.start();
 
    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
}

@Override
public void onDestroy() {
    mServiceLooper.quit();
}
3. 外部发送的事件会被依次传递到 Handler 中
@Override
public void onStart(@Nullable Intent intent, int startId) {
    Message msg = mServiceHandler.obtainMessage();
    msg.arg1 = startId;
    msg.obj = intent;
    mServiceHandler.sendMessage(msg);
}
 
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
    onStart(intent, startId);
    return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
4. 在 Handler 内会调用 onHandleIntent 方法
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(int startId) 方法来尝试停止服务。这里之所以采用 stopSelf(int startId) 而不是 stopSelf() 来停止服务,那是因为 stopSelf() 会立刻停止服务,而这个时候可能还有其他消息未处理,stopSelf(int startId) 则会等待所有的消息都处理完毕后才终止服务。一般来说,stopSelf(int startId) 在尝试停止服务之前会判断最近启动服务的次数是否和 startId 相等,如果相等就立刻停止服务,不相等则不停止服务,这个策略可以从 AMS 的 stopServiceToken 方法的实现中找到依据。

二、使用案例
1. 继承 IntentService
public class LocalIntentService extends IntentService {

    private static final String TAG = "LocalIntentService";

    public LocalIntentService() {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String action = intent.getStringExtra("task_action");
        Log.d(TAG, "handle task: " + action);
        SystemClock.sleep(2000);
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "service destroyed");
        super.onDestroy();
    }
}
2. 调用
Intent service = new Intent(this, LocalIntentService.class);
service.putExtra("task_action", "TASK1");
startService(service);
service.putExtra("task_action","TASK2"); 
startService(service);

Log 日志:

2020-12-08 13:18:43.606 D/LocalIntentService: handle task: TASK1
2020-12-08 13:18:45.606 D/LocalIntentService: handle task: TASK2
2020-12-08 13:18:47.608 D/LocalIntentService: service destroyed

相关文章

网友评论

      本文标题:Android IntentService 源码解析

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