四大组件之service
来源:互联网 发布:淘宝试用报告草稿在哪 编辑:程序博客网 时间:2024/06/06 00:50
服务
service是一个可以在后台执行长时间运行操作而不提供用户界面的应用组件。服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行。 此外,组件可以绑定到服务,以与之进行交互,甚至是执行进程间通信 (IPC)。 例如,服务可以处理网络事务、播放音乐,执行文件 I/O 或与内容提供程序交互,而所有这一切均可在后台进行。
本地服务:服务和启动它的组件在同一个进程
远程服务:服务和启动它的组件不在同一个进程
远程服务只能隐式启动,在清单文件中配置Service标签时,必须配置intent-filter子节点,并指定action子节点
启动
服务的启动可以分为两种方式:启动、绑定
- startService
- bindService
- 在服务类中创建一个内部类继承Binder,在该内部类中添加操作服务的方法,在onBind方法中返回给内部类的实例
- 在调用服务的类中,创建意图,然后调用bindService(intent, connection, BIND_AUTO_CREATE)绑定服务
- 其中connection通过 new ServiceConnection(){ }; 获取,重写两个方法:
- onServiceDisconnected(CompontName name)
- onServiceConnected(CompontName name, Ibinder service)
- Ibinder 对象就是服务类中返回的 binder 对象,通过该对象就可以访问服务中的方法
先startService,再bindService,销毁时先unbind,在stop。
创建服务
应用组件(如 Activity)可以通过调用 startService() 方法并传递 Intent 对象(指定服务并包含待使用服务的所有数据)来启动服务。服务通过 onStartCommand() 方法接收此 Intent。例如,假设某 Activity 需要将一些数据保存到在线数据库中。该 Activity 可以启动一个协同服务,并通过向 startService() 传递一个 Intent,为该服务提供要保存的数据。服务通过 onStartCommand() 接收 Intent,连接到互联网并执行数据库事务。事务完成之后,服务会自行停止运行并随即被销毁。默认情况下,服务与服务声明所在的应用运行于同一进程,而且运行于该应用的主线程中。 因此,如果服务在用户与来自同一应用的 Activity 进行交互时执行密集型或阻止性操作,则会降低 Activity 性能。 为了避免影响应用性能,应该在服务内启动新线程。
public class HelloService extends Service { private Looper mServiceLooper; private ServiceHandler mServiceHandler; private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { try { Thread.sleep(5000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } stopSelf(msg.arg1); } } @Override public void onCreate() { HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); 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(); Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; mServiceHandler.sendMessage(msg); return START_STICKY; } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onDestroy() { Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show(); }}onStartCommand() 方法必须返回整型数。整型数是一个值,用于描述系统应该如何在服务终止的情况下继续运行服务(如上所述,IntentService 的默认实现将为您处理这种情况,不过您可以对其进行修改)。从 onStartCommand() 返回的值必须是以下常量之一:
START_NOT_STICKY:如果系统在 onStartCommand() 返回后终止服务,则除非有挂起 Intent 要传递,否则系统不会重建服务。这是最安全的选项,可以避免在不必要时以及应用能够轻松重启所有未完成的作业时运行服务。
START_STICKY:如果系统在 onStartCommand() 返回后终止服务,则会重建服务并调用 onStartCommand(),但不会重新传递最后一个 Intent。相反,除非有挂起 Intent 要启动服务(在这种情况下,将传递这些 Intent ),否则系统会通过空 Intent 调用 onStartCommand()。这适用于不执行命令、但无限期运行并等待作业的媒体播放器(或类似服务)。
START_REDELIVER_INTENT:如果系统在 onStartCommand() 返回后终止服务,则会重建服务,并通过传递给服务的最后一个 Intent 调用 onStartCommand()。任何挂起 Intent 均依次传递。这适用于主动执行应该立即恢复的作业(例如下载文件)的服务。
继承IntentService 类:可以自动开启子线程处理耗时操作并且在操作完成之后自动关闭服务。IntentService 执行以下操作:
创建工作队列,用于将 Intent 逐一传递给 onHandleIntent() 实现,这样您就永远不必担心多线程问题。
在处理完所有启动请求后停止服务,因此您永远不必调用 stopSelf()。
提供 onBind() 的默认实现(返回 null)。
提供 onStartCommand() 的默认实现,可将 Intent 依次发送到工作队列和 onHandleIntent() 实现。
public class HelloService extends IntentService { //无参构造函数显式调用父类的有参构造函数 public MyIntentService() { super("MyIntentService"); } @Override protected void onHandleIntent(Intent intent) { //执行耗时操作 } @Override public void onDestroy() { super.onDestroy(); }}调用以下代码显示启动服务:
Intent intent = new Intent(this, HelloService.class);startService(intent);
Intent intent = new Intent();//创建远程的intentintent.setAction("com.gkk.homeActivity");//双引号中是点击改图标之后需要跳转到的activity过滤的意图
创建前台服务
//设置前台进程Intent intent = new Intent();//创建远程的intentintent.setAction("com.gkk.homeActivity");//双引号中是点击改图标之后需要跳转到的activity过滤的意图//四个参数分别为上下文;请求码;意图,标志位(flags);PendingIntent pIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);Notification notification = new NotificationCompat.Builder(this);.setContentIntent(pIntent);.setSmallIcon(R.drawable.main_icon);//图标.setTicker("gkk");.setContentTitle("gkk-mobile");//标题.setContentText("gkk-mobile-safe");//内容.build();startForeground(1, notification);//如果id设置为0,会导致不能设置为前台service
生命周期
服务的整个生命周期从调用 onCreate() 开始起,到 onDestroy() 返回时结束。与 Activity 类似,服务也在 onCreate() 中完成初始设置,并在 onDestroy() 中释放所有剩余资源。例如,音乐播放服务可以在 onCreate() 中创建用于播放音乐的线程,然后在 onDestroy() 中停止该线程。无论服务是通过 startService() 还是 bindService() 创建,都会为所有服务调用 onCreate() 和 onDestroy() 方法。
服务的有效生命周期从调用 onStartCommand() 或 onBind() 方法开始。每种方法均有 {Intent 对象,该对象分别传递到 startService() 或 bindService()。对于启动服务,有效生命周期与整个生命周期同时结束(即便是在 onStartCommand() 返回之后,服务仍然处于活动状态)。对于绑定服务,有效生命周期在 onUnbind() 返回时结束。
在服务中启动Activity
由于服务没有任务栈,而Activity启动之后需要放在任务栈中,所以在服务中启动Activity会抛出异常,故在服务中启动Activity需要手动设置任务栈
Intent intent = new Intent(service.this,activity.class);//服务没有任务栈,需要添加任务栈才能启动activity.intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之Service
- 四大组件之service
- Git学习之本地分支和远程分支关联
- C
- 数据字典依赖easyui onShowPanel 版本
- 在数组中找到第 k 小的数
- uikit——Auto Layout——UIView——anchor
- 四大组件之service
- 各种mysql版本下载
- HDFS常用命令
- 使用ide开发一个servlet,该servlet显示当前helloworld以及当前日期(MyEclipse)
- span标签里的内容过长设置隐藏(CSS)
- 基于CUDA的遥感影像SLIC分割
- 1002. A+B for Polynomials (25)
- Java集合--简单讲解
- leetcode 646. Maximum Length of Pair Chain