Using IntentService
makes your implementation of a started service very simple. If, however, you require your service to perform multi-threading (instead of processing start requests through a work queue), you can extend the Service
class to handle each intent.
翻译:使用IntentService比较简单,然而,如果想多线程的话,可以继承Service来处理每个intent
For comparison, the following example code shows an implementation of the Service
class that performs the same work as the previous example using IntentService
. That is, for each start request, it uses a worker thread to perform the job and processes only one request at a time.
为了对比,下面的Service和上面实现的IntentService功能一样。也就是说,每个request都会用一个worker thread 来 perform job.
一次处理一个。
public class HelloService extends Service {
private Looper serviceLooper;
private ServiceHandler serviceHandler;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Restore interrupt status.
Thread.currentThread().interrupt();
}
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf(msg.arg1);
}
}
@Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work doesn't disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
serviceLooper = thread.getLooper();
serviceHandler = new ServiceHandler(serviceLooper);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
Message msg = serviceHandler.obtainMessage();
msg.arg1 = startId;
serviceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
@Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}
As you can see, it's a lot more work than using IntentService
.
翻译:这个币IntentService写的代码要多些
However, because you handle each call to onStartCommand()
yourself, you can perform multiple requests simultaneously. That's not what this example does, but if that's what you want, you can create a new thread for each request and run them right away instead of waiting for the previous request to finish.
翻译:然而,因为你再onStartCommand里面处理每个call,所以你可以同时处理多个请求。当然示例里面不是这样做的。
但是如果你真的想这样做的话,你可以一个请求做一个thread,并且立刻执行而不是要等之前的请求执行结束。
Notice that the onStartCommand()
method must return an integer. The integer is a value that describes how the system should continue the service in the event that the system kills it. The default implementation for IntentService
handles this for you, but you are able to modify it. The return value from onStartCommand()
must be one of the following constants:
翻译:onStartCommand方法有一个返回值决定系统在kill掉这个service后如何continue it
onStartCommamd的返回值要是下面的几个常量
If the system kills the service after onStartCommand()
returns, do not recreate the service unless there are pending intents to deliver. This is the safest option to avoid running your service when not necessary and when your application can simply restart any unfinished jobs.
关键词:do not recreate the service
If the system kills the service after onStartCommand()
returns, recreate the service and call onStartCommand()
, but do not redeliver the last intent. Instead, the system calls onStartCommand()
with a null intent unless there are pending intents to start the service. In that case, those intents are delivered. This is suitable for media players (or similar services) that are not executing commands but are running indefinitely and waiting for a job.
关键词:recreate the service and call onStartCommand(),
with a null intent unless there are pending intents to start the service
很适合 media players 的场景(没在播放,但是在等待job)
If the system kills the service after onStartCommand()
returns, recreate the service and call onStartCommand()
with the last intent that was delivered to the service. Any pending intents are delivered in turn. This is suitable for services that are actively performing a job that should be immediately resumed, such as downloading a file.
关键词:ecreate the service and call onStartCommand()
with the last intent。
This is suitable for services that are actively performing a job that should be immediately resumed
很适合类似下载文件的场景
For more details about these return values, see the linked reference documentation for each constant. For an extended example of this type of service implementation, see the MessagingService
class in the MessagingService sample on GitHub.
翻译:参考。。。