参考 https://developer.android.google.cn/reference/android/app/IntentService.html
IntentService定义
IntentService继承与Service,用来处理异步请求。客户端可以通过startService(Intent)方法传递请求给IntentService。IntentService在onCreate()方法中通过HandlerThread单独开启一个线程来依次处理所有Intent请求对象所对应的任务,这样以免事务处理阻塞主线程(ANR)。执行完所一个Intent请求对象所对应的工作之后,如果没有新的Intent请求达到,则**自动停止**Service;否则执行下一个Intent请求所对应的任务。
IntentService在处理事务时,还是采用的Handler方式,创建一个名叫ServiceHandler的内部Handler,并把它直接绑定到HandlerThread所对应的子线程。 ServiceHandler把处理一个intent所对应的事务都封装到叫做onHandleIntent的抽象方法;因此我们直接实现抽象方法onHandleIntent,再在里面根据Intent的不同进行不同的事务处理就可以了。 另外,IntentService默认实现了onbind()方法,返回值为null。
源码
public abstract class IntentService extends Service { private volatile Looper mServiceLooper; private volatile ServiceHandler mServiceHandler; private String mName; private boolean mRedelivery; // 内部Handler处理 private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { onHandleIntent((Intent)msg.obj); // 关闭当前Service stopSelf(msg.arg1); } } public IntentService(String name) { super(); mName = name;e; } 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) { // 发送消息(Intent) 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); }
实现方式
定义一个TestIntentService继承IntentService
public class TestIntentService extends IntentService { // 注意构造函数参数为空,这个字符串就是WorkThread的名字 public TestIntentService() { super("TestIntentService"); } @Override public void onCreate() { Log.d("TIS","onCreate()"); super.onCreate(); } @Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { Log.d("TIS","onStartCommand()"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.d("TIS","onDestroy()"); } @Override protected void onHandleIntent(@Nullable Intent intent) { if (intent != null) { int taskId = intent.getIntExtra("taskId", -1); // 依次处理Intent请求 switch (taskId) { case 0: Log.d("TIS","handle task0"); break; case 1: Log.d("TIS","handle task1"); break; case 2: Log.d("TIS","handle task2"); break; } } } }
Manifest.xml中注册
<application ........> <activity .../> <service android:name=".service.TestIntentService" /> </application>
启动Service
//同一服务只会开启一个WorkThread,在onHandleIntent函数里依次处理Intent请求。 Intent i0 = new Intent(this, TestIntentService.class); Bundle b0 = new Bundle(); b0.putInt("taskId",0); i0.putExtras(b0); startService(i0); Intent i1 = new Intent(this, TestIntentService.class); Bundle b1 = new Bundle(); b1.putInt("taskId",1); i1.putExtras(b1); startService(i1); Intent i2 = new Intent(this, TestIntentService.class); Bundle b2 = new Bundle(); b2.putInt("taskId",2); i2.putExtras(b2); startService(i2); startService(i1); startService(i0);
运行结果及生命周期
D/TIS: onCreate() D/TIS: onStartCommand() D/TIS: handle task0 D/TIS: onStartCommand() D/TIS: onStartCommand() D/TIS: onStartCommand() D/TIS: handle task1 D/TIS: onStartCommand() D/TIS: handle task2 D/TIS: handle task1 D/TIS: handle task0 D/TIS: onDestroy()
Android Studio自动创建IntentService如下:
代码没做,模板代码是提供静态方法,方便调用,推荐使用这种方式
public class HelloIntentService extends IntentService { // TODO: Rename actions, choose action names that describe tasks that this // IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS private static final String ACTION_FOO = "com.cyxoder.interstudy.service.action.FOO"; private static final String ACTION_BAZ = "com.cyxoder.interstudy.service.action.BAZ"; // TODO: Rename parameters private static final String EXTRA_PARAM1 = "com.cyxoder.interstudy.service.extra.PARAM1"; private static final String EXTRA_PARAM2 = "com.cyxoder.interstudy.service.extra.PARAM2"; public HelloIntentService() { super("HelloIntentService"); } /** * Starts this service to perform action Foo with the given parameters. If * the service is already performing a task this action will be queued. * * @see IntentService */ // TODO: Customize helper method public static void startActionFoo(Context context, String param1, String param2) { Intent intent = new Intent(context, HelloIntentService.class); intent.setAction(ACTION_FOO); intent.putExtra(EXTRA_PARAM1, param1); intent.putExtra(EXTRA_PARAM2, param2); context.startService(intent); } /** * Starts this service to perform action Baz with the given parameters. If * the service is already performing a task this action will be queued. * * @see IntentService */ // TODO: Customize helper method public static void startActionBaz(Context context, String param1, String param2) { Intent intent = new Intent(context, HelloIntentService.class); intent.setAction(ACTION_BAZ); intent.putExtra(EXTRA_PARAM1, param1); intent.putExtra(EXTRA_PARAM2, param2); context.startService(intent); } @Override protected void onHandleIntent(Intent intent) { if (intent != null) { final String action = intent.getAction(); if (ACTION_FOO.equals(action)) { final String param1 = intent.getStringExtra(EXTRA_PARAM1); final String param2 = intent.getStringExtra(EXTRA_PARAM2); handleActionFoo(param1, param2); } else if (ACTION_BAZ.equals(action)) { final String param1 = intent.getStringExtra(EXTRA_PARAM1); final String param2 = intent.getStringExtra(EXTRA_PARAM2); handleActionBaz(param1, param2); } } } /** * Handle action Foo in the provided background thread with the provided * parameters. */ private void handleActionFoo(String param1, String param2) { // TODO: Handle action Foo throw new UnsupportedOperationException("Not yet implemented"); } /** * Handle action Baz in the provided background thread with the provided * parameters. */ private void handleActionBaz(String param1, String param2) { // TODO: Handle action Baz throw new UnsupportedOperationException("Not yet implemented"); }
原理
IntentService在onCreate()函数中通过HandlerThread单独开启一个线程来依次处理所有Intent请求对象所对应的任务。通过onStartCommand()传递给服务intent被依次插入到工作队列中。工作队列又把intent逐个发送给onHandleIntent()。
注意:所有请求都是在一个单独的工作线程上处理的——它们可能会在必要的时候(并不会阻塞应用程序的主循环),但每次只处理一个请求。