Android IntentService解析

来源:互联网 发布:双节棍 知乎 编辑:程序博客网 时间:2024/06/07 00:27

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

从实现上来看,IntentService封装了HandlerThread和Handler。(HandlerThread是一个自带handler的线程,相比较于普通线程,完成了耗时操作使用主线程handler来通知主线程更新UI,HandlerThread需要别的线程使用它自带的handler来通知它执行任务。实现也非常简单,和上一篇handler机制中我们想要自定义一个子线程并且使用handler一样,只需要创建一个Loop,并启动它的消息循环即可,这里就不再展开了。)

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


当IntentService第一次启动以后,onCreate方法会创建一个HandlerThread,然后利用它Loop来创建一个mServiceHandler,这样通过mServiceHandler发送的消息都会交给HandlerThread来处理。每次启动IntentService都会调用它的startCommand方法,startCommand调用onStart。

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


可以看到IntentService通过mServiceHandler发送了一条消息,这个消息会被HandlerThread处理,mServiceHandler收到消息后会将intent传给onHandleIntent方法处理。注意这个intent对象和外界startService传递的intent是一样的,通过这个intent可以解析出外界传递给IntetnService的参数,通过这些参数就可以区分具体的后台任务,onHandleIntent就可以进行针对性的处理。执行完毕后,IntentService会通过stopSelf(startId)来尝试停止服务,如果此时还有别的消息未处理,stopSelf(startId)会等待全部处理完毕再关闭。(通过判断最近启动服务次数和startId是否相等)

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


IntentService中的onHandleIntent方法需要我们继承之后自己实现,它可以区分intent中的参数来执行具体任务。每启动一次IntentService就等同于内部向HandlerThread发送一次请求,而Handler中的Looper是顺序执行任务的,所以intentService也是顺序执行后台任务的。

实现Demo:

public class MyIntentService extends IntentService {    private final static String TAG = "MyIntentService";    public MyIntentService() {        super(TAG);    }    @Override    protected void onHandleIntent(Intent intent) {        String action = intent.getStringExtra("task_action");        Log.i(TAG, "receive task :" + action);        SystemClock.sleep(3000);        if ("com.example.servicetest.TASK1".equals(action)) {            Log.i(TAG, "handle task :" + action);        }    }    @Override    public void onDestroy() {        super.onDestroy();        Log.i(TAG, "onDestory");    }}


在onHandleIntent中睡眠3秒模拟耗时操作,然后区分"task_action"来执行具体任务。

主线程调用:

        Intent service = new Intent(this, MyIntentService.class);        service.putExtra("task_action", "com.example.servicetest.TASK1");        startService(service);        service.putExtra("task_action", "com.example.servicetest.TASK2");        startService(service);        service.putExtra("task_action", "com.example.servicetest.TASK3");        startService(service);


要注意在AndroidManifest中注册service。

Log:

09-19 01:57:00.403 4472-4492/com.example.servicetest I/MyIntentService: receive task :com.example.servicetest.TASK109-19 01:57:03.414 4472-4492/com.example.servicetest I/MyIntentService: handle task :com.example.servicetest.TASK109-19 01:57:03.414 4472-4492/com.example.servicetest I/MyIntentService: receive task :com.example.servicetest.TASK209-19 01:57:06.424 4472-4492/com.example.servicetest I/MyIntentService: receive task :com.example.servicetest.TASK309-19 01:57:09.434 4472-4472/com.example.servicetest I/MyIntentService: onDestory


综上,IntentService是一个适合执行后台耗时操作的Service,自带消息循环机制,采用顺序的方式执行任务,可以启动多次,完成任务后自动停止。

0 0
原创粉丝点击