android IntentService浅析

参考:http://www.jianshu.com/p/8a3c44a9173a

IntentService:是Android里面的封装类,继承Service。
主要是用来处理异步请求,实现多线程。
这里写图片描述
若启动IntentService多次,那么每个耗时操作则以队列的方式在IntentService的onHandlerIntent回调方法中依次执行,执行完自动结束。

实现步骤:
1.定义IntentService的子类:传入线程名称,复用onHandleIntent方法
2.在Manifest.xml文件中注册服务
3.在Activity中开启Service服务

具体的代码:

/**
* 测试IntentService
*/
public class MyIntentService extends IntentService {
private static final String TAG = “MyIntentService”;

public MyIntentService() {
    //调用父类的构造函数
    //构造函数参数=工作线程的名字
    super("MyIntentService");
}


/**
 * 复写onHandleIntent,实现耗时的操作
 * @param intent
 */
@Override
protected void onHandleIntent(Intent intent) {
    Log.i(TAG,"MyIntentService onHandleIntent");
    //根据Intent的不同,处理不同的事务
    String taskName = intent.getExtras().getString("taskName");
    switch (taskName){
        case "task1":
            Log.i(TAG, "do task1");
            break;
        case "task2":
            Log.i(TAG, "do task2");
            break;
        default:
            break;
    }
}

@Override
public void onCreate() {
    Log.i(TAG,"MyIntentService onCreate");
    super.onCreate();
}

/**
 * 默认实现将请求的Intent添加到工作队列中
 * @param intent  请求的Intent
 * @param flags  请求的标志
 * @param startId  开始id
 * @return  返回值指示系统应该为服务当前启动状态使用什么语义。
 */
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
    Log.i(TAG,"MyIntentService onStartCommand");
    return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
    Log.i(TAG,"MyIntentService onDestroy");
    super.onDestroy();
}

}

注册:

<service
    android:name=".service.MyIntentService"
    android:exported="false"></service>

分别点击调用两个方法:

public void startIntentService1(){
    Intent i = new Intent(this,MyIntentService.class);
    Bundle bundle = new Bundle();
    bundle.putString("taskName","task1");
    i.putExtras(bundle);
    startService(i);
}

public void startIntentService2(){
    Intent i2 = new Intent(this,MyIntentService.class);
    Bundle bundle = new Bundle();
    bundle.putString("taskName","task2");
    i2.putExtras(bundle);
    startService(i2);
}

这里写图片描述
这里写图片描述
这里写图片描述

public void startIntentService1(){
    Intent i = new Intent(this,MyIntentService.class);
    Bundle bundle = new Bundle();
    bundle.putString("taskName","task1");
    i.putExtras(bundle);
    startService(i);

    Intent i2 = new Intent(this,MyIntentService.class);
    Bundle bundle2 = new Bundle();
    bundle2.putString("taskName","task2");
    i2.putExtras(bundle2);
    startService(i2);

    startService(i);//多次启动

}

这里写图片描述
从上面两种调用方法可以看出:如果方法执行完只有一个任务,那IntentService就会自己注销,执行onDestroy方法。如果一个方法中执行多次任务,就是等全部任务执行完成之后,才调用onDestroy方法,销毁服务。

源码分析:

public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper; //内部的Looper对象
    private volatile ServiceHandler mServiceHandler; //维护的ServiceHandler
    private String mName;
    private boolean mRedelivery; 

    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }
        //IntentService的handleMessage方法将接收的消息交给onHandleIntent处理,
        //onHandleIntent是一个抽象方法,使用时需要重写的方法            
        @Override
        public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
    }

    /**
     * Creates an IntentService.  Invoked by your subclass's constructor.
     *
     * @param name Used to name the worker thread, important only for debugging.
     */
    public IntentService(String name) {
        super();
        mName = name;
    }

    /**
     * Sets intent redelivery preferences.  Usually called from the constructor
     * with your preferred semantics.   
     */
    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

    @Override
    public void onCreate() {       
        super.onCreate();
        //HandlerThread继承自Thread,内部封装了Looper。
        //通过实例化HandlerThread新建线程并启动
        //所以使用IntentService时不需要额外新建线程
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();
        //获得工作线程的Looper,并维护自己的工作队列
        mServiceLooper = thread.getLooper();
        //将上述获得的Looper与新建的mServiceHandler绑定
        //新建的Handler是属于工作线程的
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        //把intent参数包装到message的obj中,然后发送信息,即添加到消息队列里
        //这里的intent就是启动服务时startService(Intent)里的Intent
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

    /**
     * You should not override this method for your IntentService. Instead,
     * override {@link #onHandleIntent}, which the system calls when the IntentService
     * receives a start request.
     * @see android.app.Service#onStartCommand
     */
    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }

    /**
     * Unless you provide binding for your service, you don't need to implement this
     * method, because the default implementation returns null.
     * @see android.app.Service#onBind
     */
    @Override
    @Nullable
    public IBinder onBind(Intent intent) {
        return null;
    }

    /**
     *   第一个人抽象方法,使用时需要重写的方法
        intent:开启服务时,可以通过Intent传入需要执行的任务标志。
     */
    @WorkerThread
    protected abstract void onHandleIntent(@Nullable Intent intent);
}

从源码中可以看出:IntentService本质就是采用Handler & HandlerThread方式:
1.通过HandlerThread单独开启一个名为IntentService的线程
2.创建一个名叫ServiceHandler的内部Handler
3.把内部Handler与HandlerThread所对应的子线程进行绑定
4.通过onStartCommand()传递给服务intent,一次插入到工作队列中,并逐个发送给onHandleIntent()
5.通过onHandleIntent来一次处理所有Intent请求对象所对应的任务

注意事项:
1.工作任务队列是顺序执行的:任务请求是逐个发送的,也就只能逐个执行
原因:onCreate方法只会调用一次,所以只会创建一个工作线程;工作线程不会多次创建,只是把消息加入消息队列中等待执行;如果服务停止,会清除消息队列中的信息,后续的事件得不到执行。

2.不建议通过bindService启动IntentService
原因:不会调用onStart或者onStartCommand方法,所以不会将消息发送到消息队列,那onHandleIntent将不会回调,就无法实现多线程的操作。

使用场景:线程任务需要按顺序、在后台执行,比如离线下载

IntentService与Service的区别:
1.Service依赖于应用程序的主线程,不建议在Service中编写耗时的逻辑和操作,否则会引起ANR;而IntentService创建一个工作线程来处理多线程任务。
2.Service需要主动调用stopSelf()来结束任务。而IntentService不需要,所有任务处理完之后,会自动关闭服务。
3.IntentService为Service的onBind方法提供了默认实现:返回null;IntentService为Service的onStartCommand方法提供了默认的实现:将请求的intent添加到队列中。

IntentService与其他线程的区别:
1.IntentService内部采用了HandlerThread实现,作用类似于后台线程;
2.与后台线程相比,IntentService是一种后台服务,优势是:优先级高,从而保证任务的执行。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值