Service的使用(二)启动服务与IntentService
2016-07-20 20:14
375 查看
创建Started Srevice
public class StartedService extends Service { private static final String TAG = "StartedService"; public StartedService() { } @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate: "); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand: "); return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy: "); } }
服务启动之后,其生命周期即独立于启动它的组件,并且可以在后台无限期地运行,即使启动服务的组件已被销毁也不受影响。 因此,服务应通过调用 stopSelf() 结束工作来自行停止运行,或者由另一个组件通过调用 stopService() 来停止它
Intent intent = new Intent(ServiceActivity.this, StartedService.class); //开始服务 startService(intent); //停止服务 stopService(intent)
首次启动Service时,onCreate才会执行。每次启动Service时,onStartCommand都会执行。如果启动时已经存在服务的实例,onCreate不会执行。
IntentService (异步的,处理完请求会自行停止)
所有的请求会进入工作队列,然后使用工作线程逐一处理所有启动请求。 只需实现 onHandleIntent() 方法即可,该方法会接收每个启动请求的 Intent。IntentService 的属性:
创建默认的工作线程,用于在应用的主线程外执行传递给 onStartCommand() 的所有 Intent。创建工作队列,用于将一个 Intent 逐一传递给 onHandleIntent() 实现,这样就不必担心多线程问题。
在处理完所有启动请求后停止服务,不必调用 stopSelf()。
提供 onBind() 的默认实现(返回 null)。
提供 onStartCommand() 的默认实现,可将 Intent 依次发送到工作队列和 onHandleIntent() 实现。
综上,只需实现 onHandleIntent() 来完成客户端提供的工作即可。(不过还需要为服务提供小型构造函数。)
示例
public class HelloIntentService extends IntentService { public HelloIntentService() { super("HelloIntentService"); } /** * The IntentService calls this method from the default worker thread with * the intent that started the service. When this method returns, IntentService * stops the service, as appropriate. */ //只需实现onHandIntent即可 @Override protected void onHandleIntent(Intent intent) { // Normally we would do some work here, like download a file. // For our sample, we just sleep for 5 seconds. long endTime = System.currentTimeMillis() + 5*1000; while (System.currentTimeMillis() < endTime) { synchronized (this) { try { wait(endTime - System.currentTimeMillis()); } catch (Exception e) { } } } } }
若有必要重写其他回调方法(如 onCreate()、onStartCommand() 或 onDestroy()),要确保调用超类实现,以便 IntentService 能够妥善处理工作线程的生命周期。
例如:
@Override public int onStartCommand(Intent intent, int flags, int startId) { Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); //调用超类 return super.onStartCommand(intent,flags,startId); }
多线程处理请求
public class HelloService extends Service { private Looper mServiceLooper; private ServiceHandler mServiceHandler; // 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. long endTime = System.currentTimeMillis() + 5*1000; while (System.currentTimeMillis() < endTime) { synchronized (this) { try { wait(endTime - System.currentTimeMillis()); } catch (Exception e) { } } } // 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 will not 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 mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); } @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 = mServiceHandler.obtainMessage(); msg.arg1 = startId; mServiceHandler.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(); } }
onStartCommand的返回值
onStartCommand() 方法必须返回整型数,用于描述系统应该如何在服务终止的情况下继续运行服务。必须是以下值之一:
START_NOT_STICKY
如果系统在 onStartCommand() 返回后终止服务,则除非有挂起 Intent 要传递,否则系统不会重建服务。这是最安全的选项,可以避免在不必要时以及应用能够轻松重启所有未完成的作业时运行服务。
START_STICKY
如果系统在 onStartCommand() 返回后终止服务,则会重建服务并调用 onStartCommand(),但绝对不会重新传递最后一个 Intent。相反,除非有挂起 Intent 要启动服务(在这种情况下,将传递这些 Intent ),否则系统会通过空 Intent 调用 onStartCommand()。这适用于不执行命令、但无限期运行并等待作业的媒体播放器(或类似服务)。
START_REDELIVER_INTENT
如果系统在 onStartCommand() 返回后终止服务,则会重建服务,并通过传递给服务的最后一个 Intent 调用 onStartCommand()。任何挂起 Intent 均依次传递。这适用于主动执行应该立即恢复的作业(例如下载文件)的服务。
与IntentService的区别
以上示例中,每个请求都分配一个工作线程来处理请求,且每个工作线程执行完任务后就会关闭,不会处理其他请求。而IntentService自始至终只有一个工作线程,处理完一个请求后,继续处理队列中的请求,不会关闭。另外,虽然都是处理很多请求,以上示例其实是同时处理,而IntentService是逐一处理。(实际应用中貌似都用IntentService)相关文章推荐
- Android IPC进程间通讯机制
- android之定时器AlarmManager
- axis备忘
- Windows XP Service Pack 3 RC1 v.3244 winxp补丁3 提供下载
- Run As Service runassrv.exe 详细参数第1/2页
- 安装MySQL在最后的start service停住了解决方法
- Android IPC机制绑定Service实现本地通信
- android使用Messenger绑定Service的多种实现方法
- asp.net Web Service 接口大量数据传输解决方案
- Silverlight中动态获取Web Service地址
- android调用web service(cxf)实例应用详解
- 在Android中 获取正在运行的Service 实例
- ASP.NET State service状态服务的问题解决方法
- 卸载ZkeysPHP 后iis网站出现Service Unavailable 解决办法
- IIS Admin Service 服务因 2149647636 (0x80210514) 服务性错误而停止
- Service Temporarily Unavailable的503错误是怎么回事?
- 深入剖析Android系统中Service和IntentService的区别
- Android中Service服务详解(一)
- android教程之service使用方法示例详解