IntentService.java revision f6f9f2d0256930ce0bb4913b2260b8480914edc2
1package android.app;
2
3import android.content.Intent;
4import android.os.Handler;
5import android.os.HandlerThread;
6import android.os.IBinder;
7import android.os.Looper;
8import android.os.Message;
9
10/**
11 * An abstract {@link Service} that serializes the handling of the Intents passed upon service
12 * start and handles them on a handler thread.
13 *
14 * <p>To use this class extend it and implement {@link #onHandleIntent}. The {@link Service} will
15 * automatically be stopped when the last enqueued {@link Intent} is handled.
16 */
17public abstract class IntentService extends Service {
18    private volatile Looper mServiceLooper;
19    private volatile ServiceHandler mServiceHandler;
20    private String mName;
21    private boolean mRedelivery;
22
23    private final class ServiceHandler extends Handler {
24        public ServiceHandler(Looper looper) {
25            super(looper);
26        }
27
28        @Override
29        public void handleMessage(Message msg) {
30            onHandleIntent((Intent)msg.obj);
31            stopSelf(msg.arg1);
32        }
33    }
34
35    public IntentService(String name) {
36        super();
37        mName = name;
38    }
39
40    /**
41     * Control redelivery of intents.  If called with true,
42     * {@link #onStartCommand(Intent, int, int)} will return
43     * {@link Service#START_REDELIVER_INTENT} instead of
44     * {@link Service#START_NOT_STICKY}, so that if this service's process
45     * is called while it is executing the Intent in
46     * {@link #onHandleIntent(Intent)}, then when later restarted the same Intent
47     * will be re-delivered to it, to retry its execution.
48     */
49    public void setIntentRedelivery(boolean enabled) {
50        mRedelivery = enabled;
51    }
52
53    @Override
54    public void onCreate() {
55        super.onCreate();
56        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
57        thread.start();
58
59        mServiceLooper = thread.getLooper();
60        mServiceHandler = new ServiceHandler(mServiceLooper);
61    }
62
63    @Override
64    public void onStart(Intent intent, int startId) {
65        Message msg = mServiceHandler.obtainMessage();
66        msg.arg1 = startId;
67        msg.obj = intent;
68        mServiceHandler.sendMessage(msg);
69    }
70
71    @Override
72    public int onStartCommand(Intent intent, int flags, int startId) {
73        onStart(intent, startId);
74        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
75    }
76
77    @Override
78    public void onDestroy() {
79        mServiceLooper.quit();
80    }
81
82    @Override
83    public IBinder onBind(Intent intent) {
84        return null;
85    }
86
87    /**
88     * Invoked on the Handler thread with the {@link Intent} that is passed to {@link #onStart}.
89     * Note that this will be invoked from a different thread than the one that handles the
90     * {@link #onStart} call.
91     */
92    protected abstract void onHandleIntent(Intent intent);
93}
94