IntentService.java revision 15a4d2ffd04dc6c70f2cd17dae12ac6bc14c69ab
1637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne/*
2637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne * Copyright (C) 2008 The Android Open Source Project
3637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne *
4637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne * Licensed under the Apache License, Version 2.0 (the "License");
5637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne * you may not use this file except in compliance with the License.
6637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne * You may obtain a copy of the License at
7637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne *
8637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne *      http://www.apache.org/licenses/LICENSE-2.0
9637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne *
10637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne * Unless required by applicable law or agreed to in writing, software
11637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne * distributed under the License is distributed on an "AS IS" BASIS,
12637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne * See the License for the specific language governing permissions and
14637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne * limitations under the License.
15637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne */
16637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne
17637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhnepackage android.app;
18637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne
19fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silbersteinimport android.content.Intent;
20d0258ee4816148ff4ab9ac6b854fc5c51ea53be3Amin Shaikhimport android.os.Handler;
21736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wileyimport android.os.HandlerThread;
22dc93140010ce36189b29fd58bc8f25d7636101f5Rebecca Silbersteinimport android.os.IBinder;
23ed63ba7401bc545513ca91dfbb683aec4c3851dcChristopher Wileyimport android.os.Looper;
2479d069c37009c62f4f9e1dd0fc623fcf50aab919Rebecca Silbersteinimport android.os.Message;
25b4de842310ca698d59ed5b9117d38362e2945947Rebecca Silberstein
26dc93140010ce36189b29fd58bc8f25d7636101f5Rebecca Silberstein/**
273c0eb618a6398926893508f9d05fa39a99cf4894Sohani Rao * An abstract {@link Service} that serializes the handling of the Intents passed upon service
28fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein * start and handles them on a handler thread.
29ed63ba7401bc545513ca91dfbb683aec4c3851dcChristopher Wiley *
30736132bc7bc92bf17cbeeea26f0bf44d498e46e0Christopher Wiley * <p>To use this class extend it and implement {@link #onHandleIntent}. The {@link Service} will
31e4b4b229331da3964671606f18557b2e7f681b45Amin Shaikh * automatically be stopped when the last enqueued {@link Intent} is handled.
32ed63ba7401bc545513ca91dfbb683aec4c3851dcChristopher Wiley */
33fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silbersteinpublic abstract class IntentService extends Service {
34fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein    private volatile Looper mServiceLooper;
35ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius    private volatile ServiceHandler mServiceHandler;
36259fb5a5265e0a2aa8a851d5e694d28afe9a87f2Mitchell Wills    private String mName;
37d0258ee4816148ff4ab9ac6b854fc5c51ea53be3Amin Shaikh    private boolean mRedelivery;
38ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius
39fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein    private final class ServiceHandler extends Handler {
403c0eb618a6398926893508f9d05fa39a99cf4894Sohani Rao        public ServiceHandler(Looper looper) {
41fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein            super(looper);
42e445510f55e09d4c63ad08d725395563038cee76Roshan Pius        }
43e445510f55e09d4c63ad08d725395563038cee76Roshan Pius
449432358b816df5530aed86d4107756854e5ac4f0Peter Qiu        @Override
45eaa6ff2e246151fe8f42d7111541225ee0e3f346Peter Qiu        public void handleMessage(Message msg) {
4650f36ec6fe906445db996bf3918e5cb3f170bc79Peter Qiu            onHandleIntent((Intent)msg.obj);
47ae791278c9032a8b10cf818b98b571c0396add4aPeter Qiu            stopSelf(msg.arg1);
48163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius        }
49163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius    }
50163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius
5192f4d52b14d8847f6f81712bf3bbfa0f1203eef5Sohani Rao    public IntentService(String name) {
5292f4d52b14d8847f6f81712bf3bbfa0f1203eef5Sohani Rao        super();
53fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein        mName = name;
54637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne    }
55ed63ba7401bc545513ca91dfbb683aec4c3851dcChristopher Wiley
56fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein    /**
57fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein     * Control redelivery of intents.  If called with true,
58ed63ba7401bc545513ca91dfbb683aec4c3851dcChristopher Wiley     * {@link #onStartCommand(Intent, int, int)} will return
59ed63ba7401bc545513ca91dfbb683aec4c3851dcChristopher Wiley     * {@link Service#START_REDELIVER_INTENT} instead of
60fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein     * {@link Service#START_NOT_STICKY}, so that if this service's process
61637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne     * is killed while it is executing the Intent in
62637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne     * {@link #onHandleIntent(Intent)}, then when later restarted the same Intent
63fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein     * will be re-delivered to it, to retry its execution.
64ed63ba7401bc545513ca91dfbb683aec4c3851dcChristopher Wiley     */
65637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne    public void setIntentRedelivery(boolean enabled) {
66fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein        mRedelivery = enabled;
67637a86ffb3a036a4f26a471378b57d8817f35c25Glen Kuhne    }
68fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein
69fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein    @Override
70fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein    public void onCreate() {
71fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein        super.onCreate();
72fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
73fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein        thread.start();
74fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein
75990818e78ab62c0ae0ec5b0b24803aed664feaebRebecca Silberstein        mServiceLooper = thread.getLooper();
76e445510f55e09d4c63ad08d725395563038cee76Roshan Pius        mServiceHandler = new ServiceHandler(mServiceLooper);
77b8b3fb8228a1f90106bad8c59ce006b81ef7921cRoshan Pius    }
78163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius
79163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius    @Override
80b4419d876beda78c29836726e43d80203b4a656cRoshan Pius    public void onStart(Intent intent, int startId) {
8179d22abe8ab440408ac1d568ddced7efd1a19278Tomasz Wiszkowski        Message msg = mServiceHandler.obtainMessage();
828c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius        msg.arg1 = startId;
83fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein        msg.obj = intent;
84fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein        mServiceHandler.sendMessage(msg);
85fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein    }
86fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein
87fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein    @Override
8870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang    public int onStartCommand(Intent intent, int flags, int startId) {
89107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne        onStart(intent, startId);
90107f6ce4a5f6017ce336d9b60650ddbe28bee965Glen Kuhne        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
91fca64fc16ec43befde2e7ac7c3bfd84ced1f7778Rebecca Silberstein    }
92f74a1cfd50d7b44aa7e4b598eb229cd464983dfemukesh agrawal
93b6d6e31dc6ed9a9a0178990a0cec8edb9ad36c77mukesh agrawal    @Override
94ee0ab818341d44614ffe56ae73ecc08b974c2cbbRoshan Pius    public void onDestroy() {
953204fb9682242a7b5a749489076c66d448c42577Roshan Pius        mServiceLooper.quit();
9661312e14a088a9487d4db64f08285162476e870fPaul Stewart    }
97a6eb5e6da171c5426a96a8d0f97c75d1b8a46db0Roshan Pius
98e445510f55e09d4c63ad08d725395563038cee76Roshan Pius    @Override
99e445510f55e09d4c63ad08d725395563038cee76Roshan Pius    public IBinder onBind(Intent intent) {
100e445510f55e09d4c63ad08d725395563038cee76Roshan Pius        return null;
101e445510f55e09d4c63ad08d725395563038cee76Roshan Pius    }
102a6eb5e6da171c5426a96a8d0f97c75d1b8a46db0Roshan Pius
1036c90568a19e32a1825e06a608e59d3f36daff9caRandy Pan    /**
104d0258ee4816148ff4ab9ac6b854fc5c51ea53be3Amin Shaikh     * Invoked on the Handler thread with the {@link Intent} that is passed to {@link #onStart}.
10550f36ec6fe906445db996bf3918e5cb3f170bc79Peter Qiu     * Note that this will be invoked from a different thread than the one that handles the
106d0258ee4816148ff4ab9ac6b854fc5c51ea53be3Amin Shaikh     * {@link #onStart} call.
107d0258ee4816148ff4ab9ac6b854fc5c51ea53be3Amin Shaikh     */
108dc93140010ce36189b29fd58bc8f25d7636101f5Rebecca Silberstein    protected abstract void onHandleIntent(Intent intent);
10992f4d52b14d8847f6f81712bf3bbfa0f1203eef5Sohani Rao}
11092f4d52b14d8847f6f81712bf3bbfa0f1203eef5Sohani Rao