深入理解IntentService

对比: IntentService是Service的子类,和Service不同的是,IntentService内部已经实现绑定好一个工作线程,因此,在IntentService中可以直接执行耗时操作,这样就省下了我们要在Service中人为创建线程来处理耗时操作的时间,减轻了工作量。

IntentService是可以处理异步请求的Service。每次所有的请求都会被放置在Looper管理的消息队列中。当消息队列不为空的时候,会依次取出请求并交给工作线程处理,直至所有的请求被处理完成。线程结束后将会自动停止。需要注意的是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);
        }
    }


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

    protected abstract void onHandleIntent(Intent intent);
}

IntentService是由Looper,Handler,Service共同组合而成。
1、IntentService在创建时执行onCreate()。在创建HandlerThread线程后,获取当前线程的Looper对象来初始化mServiceLooper,接着创建mServiceHandler。在此过程中工作线程和mServiceHandler进行了绑定。

2、启动IntentService时,产生一条Message(携带startId和Intent),并将该Message发送到MessageQueue中。然后,Looper一旦发现该Message,则将该Message交给mServiceHandler中的handleMessage处理。

3、接着会调用onHandleIntent()来处理。这个方法是抽象方法,需要我们在子类中重写该方法实现相关的处理逻辑。任务一旦完成就会调用stopSelf()来结束指定的工作线程。值得注意的是onHandleIntent()是运行在工作线程当中的。

4、当所有的工作完成之后,执行onDestory()方法,其中通过调用mServiceLooper.quit()来在服务结束时停止Looper。


总结:
IntentService是基于消息队列(MessageQueue)的服务,,每次启动服务并不会马上处理工作,而是首先创建对应的Looper、Handler。任务的执行顺序即queue队列Message的顺序(排队执行)。任务一旦完成,将会自行停止。因此其使用范围多在以下几种情况:

更新客户端版本
需要在后台执行单任务
多个允许异步执行的后台任务(无前后顺序和时间顺序的要求)
优缺点:
使用方便,避开了我们自己需要Service中创建线程。
由于只有一个工作线程,所有任务的执行都需要排队,因为不适合对任务并发的情况。


简单测试:

public class MainActivity extends Activity {
    @Override
     public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Log.d("IntentService", "ui thread name:"+Thread.currentThread().getName());
            for(int i=0;i<10;i++)
            startService(new Intent(this, AsyncService.class));
    }

}

public class AsyncService extends IntentService {


    public AsyncService() {
        super("async");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        try {
            Log.d("IntentService", "work thread name:"+Thread.currentThread().getName());
            Thread.sleep(7000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

运行结果:
1、耗时操作未产生ANR
2、输出的Log日志为:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值