IntentService解析及使用规范
一、概述
IntentService继承于Service用来在后台处理异步请求。客户端通过
Context#startService(Intent)发送请求,IntentService按顺序在后台工作线程里处理每一个Intent,并且当处理完所有Intent就会停止。
#1-1 使用示例
#MainActivity.java
String param = "this is a test case.";
TestIntentService.startActionTest(this,param);
#TestIntentService.java
public class TestIntentService extends IntentService {
private static final String TAG = "TestIntentService";
private static final String ACTION_TEST = "action.TEST";
private static final String EXTRA_PARAM1 = "extra.PARAM1";
public TestIntentService() {
super("TestIntentService");
}
public static void startActionTest(Context context, String param1) {
Intent intent = new Intent(context, TestIntentService.class);
intent.setAction(ACTION_TEST);
intent.putExtra(EXTRA_PARAM1, param1);
context.startService(intent);
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_TEST.equals(action)) {
final String param1 = intent.getStringExtra(EXTRA_PARAM1);
handleActionTest(param1);
}
}
}
private void handleActionTest(String param1) {
Log.d(TAG,"handleActionTest(String param1) param1:" + param1);
}
}
二、IntentService
#2-1 源代码
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(@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;
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
@Override
@Nullable
public IBinder onBind(Intent intent) {
return null;
}
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
}
#2-2 创建Service
在Service被创建的时候,使用HandlerThread(继承于 Thread)创建一个多线程并运行起来,使用HandlerThread线程的Looper来创建一个Handler,使得此Handler处理的所有任务都运行在非主线程里。
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
#2-3 处理任务
onStart在高版本SDK被onStartCommand替代,为了兼容低版本在onStartCommand调用onStart方法。任务最终通过运行在非主线程的onHandleIntent执行。
-----------------------------------------
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
-----------------------------------------
@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_STICK;
}
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
#2-4 销毁Service
任务执行完毕后会调用stopSelf,在没有任何任务正在执行或即将执行的情况下Service会停止运行。
-----------------------------------------
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
----------------------------------------
#2-5 注意事项
Service停止运行时要注意使用mServiceLooper.quit()退出Looper。如果不提供绑定服务默认返回null。
@Override
public void onDestroy() {
mServiceLooper.quit();
}
@Override
@Nullable
public IBinder onBind(Intent intent) {
return null;
}
三、知识点总结
#3-1 HandlerThread
使用HandlerThread和Handler创建一个子线程独立运行,Handler#sendMessage(msg)将任务放在该子线程即将执行的任务队列里。
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
#3-2 Handler
使用Handler发送消息时通过obtainMessage()来获取消息,它有个消息池可以循环利用避免创建过多的Message消耗不必要的内存
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);