IntentService原理
2018-03-05 本文已影响0人
帝王鲨kingcp
IntentService是一个特殊的Service,它继承Service并且它是一个抽象类,因此必须创建它的子类才能使用。IntentService因为是一个Service,所以适用优先级要求高的后台线程,线程结束,IntentService就结束了。
在IntentService被初始化时候,会创建一个HandlerThread和ServiceHandler,用于实现整个流程。
@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();
// 1. 通过实例化HandlerThread新建线程 & 启动;故 使用IntentService时,不需额外新建线程
// HandlerThread继承自Thread,内部封装了 Looper
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
// 2. 获得工作线程的 Looper & 维护自己的工作队列
mServiceLooper = thread.getLooper();
// 3. 新建mServiceHandler & 绑定上述获得Looper
mServiceHandler = new ServiceHandler(mServiceLooper);
}
HandlerThread
HandlerThread继承Thread,是一个可以使用Handler的Thread。run方法中通过Looper.prepare,Looper.loop形成消息循环队里。HandlerThread与普通Thread的区别在于HandlerThread需要通过handler来交待一个具体的任务。HandlerThread就用在IntentService,在后台线程为其提供一个消息队列。
public class HandlerThread extends Thread {
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
}
在使用IntentService时,用start开启任务。start会将任务交给mServiceHandler中的handleMessage来处理。具体是处理由onHandleIntent来完成,子类会重写这个方法。然后stopSelf(int startId)来结束(会等所有消息处理完后才终止服务)。
@Override
public void onStart(@Nullable Intent intent, int startId) {
// 1. 获得ServiceHandler消息的引用
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
// 2. 把 Intent参数 包装到 message 的 obj 发送消息中,
//这里的Intent = 启动服务时startService(Intent) 里传入的 Intent
msg.obj = intent;
// 3. 发送消息,即 添加到消息队列里
mServiceHandler.sendMessage(msg);
}
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
// IntentService的handleMessage()把接收的消息交给onHandleIntent()处理
@Override
public void handleMessage(Message msg) {
// onHandleIntent 方法在工作线程中执行
// onHandleIntent() = 抽象方法,使用时需重写
onHandleIntent((Intent)msg.obj);
// 执行完调用 stopSelf() 结束服务
stopSelf(msg.arg1);
}
}
IntentService实例
启动3次intentService,三次任务会排队依次执行。
public class IntentService_Activity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.intentservice_activity);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(IntentService_Activity.this,IntentService_Service.class);
intent.putExtra("task_name","service_task1");
startService(intent);
intent.putExtra("task_name","service_task2");
startService(intent);
intent.putExtra("task_name","service_task3");
startService(intent);
}
});
}
}
public class IntentService_Service extends IntentService {
private static final String TAG = "IntentService_Service";
public IntentService_Service() {
// 调用父类的构造函数
// 参数 = 工作线程的名字
super(TAG);
Log.i(TAG, "IntentService_Service: 初始化");
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate: ");
}
/**
* 复写onHandleIntent()方法
* 根据 Intent实现 耗时任务 操作
**/
@Override
protected void onHandleIntent(@Nullable Intent intent) {
Log.i(TAG, "onHandleIntent: begin task " + intent.getStringExtra("task_name"));
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy: 队列中人任务已完成");
}
}
执行结果如下:若启动IntentService 多次,那么每个耗时操作则以队列的方式在IntentService的 onHandleIntent回调方法中依次执行,执行完自动结束
执行结果.png