1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.app; 18 19 import android.annotation.Nullable; 20 import android.annotation.WorkerThread; 21 import android.compat.annotation.UnsupportedAppUsage; 22 import android.content.Intent; 23 import android.os.Handler; 24 import android.os.HandlerThread; 25 import android.os.IBinder; 26 import android.os.Looper; 27 import android.os.Message; 28 29 /** 30 * IntentService is a base class for {@link Service}s that handle asynchronous 31 * requests (expressed as {@link Intent}s) on demand. Clients send requests 32 * through {@link android.content.Context#startService(Intent)} calls; the 33 * service is started as needed, handles each Intent in turn using a worker 34 * thread, and stops itself when it runs out of work. 35 * 36 * <p>This "work queue processor" pattern is commonly used to offload tasks 37 * from an application's main thread. The IntentService class exists to 38 * simplify this pattern and take care of the mechanics. To use it, extend 39 * IntentService and implement {@link #onHandleIntent(Intent)}. IntentService 40 * will receive the Intents, launch a worker thread, and stop the service as 41 * appropriate. 42 * 43 * <p>All requests are handled on a single worker thread -- they may take as 44 * long as necessary (and will not block the application's main loop), but 45 * only one request will be processed at a time. 46 * 47 * <div class="special reference"> 48 * <h3>Developer Guides</h3> 49 * <p>For a detailed discussion about how to create services, read the 50 * <a href="{@docRoot}guide/components/services.html">Services</a> developer 51 * guide.</p> 52 * </div> 53 * 54 * @see android.support.v4.app.JobIntentService 55 * 56 * @deprecated IntentService is subject to all the 57 * <a href="/preview/features/background.html">background execution limits</a> 58 * imposed with Android 8.0 (API level 26). Consider using {@link androidx.work.WorkManager} 59 * or {@link androidx.core.app.JobIntentService}, which uses jobs 60 * instead of services when running on Android 8.0 or higher. 61 */ 62 @Deprecated 63 public abstract class IntentService extends Service { 64 private volatile Looper mServiceLooper; 65 @UnsupportedAppUsage 66 private volatile ServiceHandler mServiceHandler; 67 private String mName; 68 private boolean mRedelivery; 69 70 private final class ServiceHandler extends Handler { ServiceHandler(Looper looper)71 public ServiceHandler(Looper looper) { 72 super(looper); 73 } 74 75 @Override handleMessage(Message msg)76 public void handleMessage(Message msg) { 77 onHandleIntent((Intent)msg.obj); 78 stopSelf(msg.arg1); 79 } 80 } 81 82 /** 83 * Creates an IntentService. Invoked by your subclass's constructor. 84 * 85 * @param name Used to name the worker thread, important only for debugging. 86 */ IntentService(String name)87 public IntentService(String name) { 88 super(); 89 mName = name; 90 } 91 92 /** 93 * Sets intent redelivery preferences. Usually called from the constructor 94 * with your preferred semantics. 95 * 96 * <p>If enabled is true, 97 * {@link #onStartCommand(Intent, int, int)} will return 98 * {@link Service#START_REDELIVER_INTENT}, so if this process dies before 99 * {@link #onHandleIntent(Intent)} returns, the process will be restarted 100 * and the intent redelivered. If multiple Intents have been sent, only 101 * the most recent one is guaranteed to be redelivered. 102 * 103 * <p>If enabled is false (the default), 104 * {@link #onStartCommand(Intent, int, int)} will return 105 * {@link Service#START_NOT_STICKY}, and if the process dies, the Intent 106 * dies along with it. 107 */ setIntentRedelivery(boolean enabled)108 public void setIntentRedelivery(boolean enabled) { 109 mRedelivery = enabled; 110 } 111 112 @Override onCreate()113 public void onCreate() { 114 // TODO: It would be nice to have an option to hold a partial wakelock 115 // during processing, and to have a static startService(Context, Intent) 116 // method that would launch the service & hand off a wakelock. 117 118 super.onCreate(); 119 HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); 120 thread.start(); 121 122 mServiceLooper = thread.getLooper(); 123 mServiceHandler = new ServiceHandler(mServiceLooper); 124 } 125 126 @Override onStart(@ullable Intent intent, int startId)127 public void onStart(@Nullable Intent intent, int startId) { 128 Message msg = mServiceHandler.obtainMessage(); 129 msg.arg1 = startId; 130 msg.obj = intent; 131 mServiceHandler.sendMessage(msg); 132 } 133 134 /** 135 * You should not override this method for your IntentService. Instead, 136 * override {@link #onHandleIntent}, which the system calls when the IntentService 137 * receives a start request. 138 * @see android.app.Service#onStartCommand 139 */ 140 @Override onStartCommand(@ullable Intent intent, int flags, int startId)141 public int onStartCommand(@Nullable Intent intent, int flags, int startId) { 142 onStart(intent, startId); 143 return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; 144 } 145 146 @Override onDestroy()147 public void onDestroy() { 148 mServiceLooper.quit(); 149 } 150 151 /** 152 * Unless you provide binding for your service, you don't need to implement this 153 * method, because the default implementation returns null. 154 * @see android.app.Service#onBind 155 */ 156 @Override 157 @Nullable onBind(Intent intent)158 public IBinder onBind(Intent intent) { 159 return null; 160 } 161 162 /** 163 * This method is invoked on the worker thread with a request to process. 164 * Only one Intent is processed at a time, but the processing happens on a 165 * worker thread that runs independently from other application logic. 166 * So, if this code takes a long time, it will hold up other requests to 167 * the same IntentService, but it will not hold up anything else. 168 * When all requests have been handled, the IntentService stops itself, 169 * so you should not call {@link #stopSelf}. 170 * 171 * @param intent The value passed to {@link 172 * android.content.Context#startService(Intent)}. 173 * This may be null if the service is being restarted after 174 * its process has gone away; see 175 * {@link android.app.Service#onStartCommand} 176 * for details. 177 */ 178 @WorkerThread onHandleIntent(@ullable Intent intent)179 protected abstract void onHandleIntent(@Nullable Intent intent); 180 } 181