IntentService源码
1 /** 2 * IntentService is a base class for {@link Service}s that handle asynchronous 3 * requests (expressed as {@link Intent}s) on demand. Clients send requests 4 * through {@link android.content.Context#startService(Intent)} calls; the 5 * service is started as needed, handles each Intent in turn using a worker 6 * thread, and stops itself when it runs out of work. 7 * 8 * <p>This "work queue processor" pattern is commonly used to offload tasks 9 * from an application's main thread. The IntentService class exists to 10 * simplify this pattern and take care of the mechanics. To use it, extend 11 * IntentService and implement {@link #onHandleIntent(Intent)}. IntentService 12 * will receive the Intents, launch a worker thread, and stop the service as 13 * appropriate. 14 * 15 * <p>All requests are handled on a single worker thread -- they may take as 16 * long as necessary (and will not block the application's main loop), but 17 * only one request will be processed at a time. 18 * 19 * <div class="special reference"> 20 * <h3>Developer Guides</h3> 21 * <p>For a detailed discussion about how to create services, read the 22 * <a href="{@docRoot}guide/components/services.html">Services</a> developer 23 * guide.</p> 24 * </div> 25 * 26 * @see android.os.AsyncTask 27 */ 28 public abstract class IntentService extends Service { 29 private volatile Looper mServiceLooper; 30 private volatile ServiceHandler mServiceHandler; 31 private String mName; 32 private boolean mRedelivery; 33 34 private final class ServiceHandler extends Handler { 35 public ServiceHandler(Looper looper) { 36 super(looper); 37 } 38 39 @Override 40 public void handleMessage(Message msg) { 41 onHandleIntent((Intent)msg.obj); 42 stopSelf(msg.arg1); 43 } 44 } 45 46 /** 47 * Creates an IntentService. Invoked by your subclass's constructor. 48 * 49 * @param name Used to name the worker thread, important only for debugging. 50 */ 51 public IntentService(String name) { 52 super(); 53 mName = name; 54 } 55 56 /** 57 * Sets intent redelivery preferences. Usually called from the constructor 58 * with your preferred semantics. 59 * 60 * <p>If enabled is true, 61 * {@link #onStartCommand(Intent, int, int)} will return 62 * {@link Service#START_REDELIVER_INTENT}, so if this process dies before 63 * {@link #onHandleIntent(Intent)} returns, the process will be restarted 64 * and the intent redelivered. If multiple Intents have been sent, only 65 * the most recent one is guaranteed to be redelivered. 66 * 67 * <p>If enabled is false (the default), 68 * {@link #onStartCommand(Intent, int, int)} will return 69 * {@link Service#START_NOT_STICKY}, and if the process dies, the Intent 70 * dies along with it. 71 */ 72 public void setIntentRedelivery(boolean enabled) { 73 mRedelivery = enabled; 74 } 75 76 @Override 77 public void onCreate() { 78 // TODO: It would be nice to have an option to hold a partial wakelock 79 // during processing, and to have a static startService(Context, Intent) 80 // method that would launch the service & hand off a wakelock. 81 82 super.onCreate(); 83 HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); 84 thread.start(); 85 86 mServiceLooper = thread.getLooper(); 87 mServiceHandler = new ServiceHandler(mServiceLooper); 88 } 89 90 @Override 91 public void onStart(@Nullable Intent intent, int startId) { 92 Message msg = mServiceHandler.obtainMessage(); 93 msg.arg1 = startId; 94 msg.obj = intent; 95 mServiceHandler.sendMessage(msg); 96 } 97 98 /** 99 * You should not override this method for your IntentService. Instead, 100 * override {@link #onHandleIntent}, which the system calls when the IntentService 101 * receives a start request. 102 * @see android.app.Service#onStartCommand 103 */ 104 @Override 105 public int onStartCommand(@Nullable Intent intent, int flags, int startId) { 106 onStart(intent, startId); 107 return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; 108 } 109 110 @Override 111 public void onDestroy() { 112 mServiceLooper.quit(); 113 } 114 115 /** 116 * Unless you provide binding for your service, you don't need to implement this 117 * method, because the default implementation returns null. 118 * @see android.app.Service#onBind 119 */ 120 @Override 121 @Nullable 122 public IBinder onBind(Intent intent) { 123 return null; 124 } 125 126 /** 127 * This method is invoked on the worker thread with a request to process. 128 * Only one Intent is processed at a time, but the processing happens on a 129 * worker thread that runs independently from other application logic. 130 * So, if this code takes a long time, it will hold up other requests to 131 * the same IntentService, but it will not hold up anything else. 132 * When all requests have been handled, the IntentService stops itself, 133 * so you should not call {@link #stopSelf}. 134 * 135 * @param intent The value passed to {@link 136 * android.content.Context#startService(Intent)}. 137 * This may be null if the service is being restarted after 138 * its process has gone away; see 139 * {@link android.app.Service#onStartCommand} 140 * for details. 141 */ 142 @WorkerThread 143 protected abstract void onHandleIntent(@Nullable Intent intent); 144 }