首页 > 其他分享 >android services 使用

android services 使用

时间:2023-07-28 19:05:07浏览次数:38  
标签:service onStartCommand 一个 应用程序 组件 intent 使用 services android


Android之Services


Services

  一个Service是一个应用程序组件,它能完成长时间运行的操作在后台,并且不提供用户接口。另一个应用程序组件能开启一个service并 且它将继续运行在后台即使用户转换到另一个应用程序。额外的,一个组件可以被绑定到一个service来和它交互甚至完成进程间通信。例如,一个 service可能操作网络带伤、播放音乐、执行I/O或和一个content provider交互,所有这些都是在后台进行。

  一个service主要有两个用途:

  1、Started

    一个service被开启当一个应用程序组件(例如activity)用startService()开启它。一旦开启,一个 service能无期限的运行在后台,即使创建它的组件被销毁。通常,一个启动的service完成一个单的操作,并且不返回结果给调用者。例如,它可能 下载蔌上传一个文件通过网络。当操作完成,服务应该停止它自己。

  2、Bound

    一个service处于Bound状态,当一个应用程序组件绑定它通过bindService()。一个bound service提供一个客户端/服务器接口,以允许组件和service交互、发送请求、获取结果甚至做跨进程的进程间通信(IPC)。一个bound service运行只有当另一个应用程序组件绑定它。更多的是,组件能一旦绑定到service,但当它们所有都取消绑定,这个service就被摧毁。

  虽然这篇文档主要单独地讨论两种不同类型的service,你的service可以两个都工作--它可以启动(无期限的运行)并且同样允许绑 定。这只是你的组件是否实现了两个onStartComamnd()回调的问题,来允许组件启动它并且onBind()允许绑定。

  不管你的应用程序是否启动、bound、或两个都是,任何一个应用程序组件都可以使用service(甚至从一个单独的应用程序),通过这种方 式,任何组件能使用一个activity--通过一个Intent开启。可是,你能声明service私有,在manifest文件里,并且阻止访问从其 它应用程序。

  警告 :一个service支它的主进程的主线程--service不创建它自己的线程并且不运行在单独的进 程(除非你指定)。这意味着,如果你的service将要去做任何耗CPU的工作或阻塞操作(例如MP3播放或网络),你应该新建一个线程为这个 service来完成那个工作。通过使用一个单独的线程,你将减少应用程序不响应(ANR)风险并且应用程序的主线程能专注于你的activity的用户 交互。

The Basics

  为了创建一个service,你必须创建一个service的子类(或已经存在类的子类)。在你的实现中,你需要需要覆盖一些回调函数,那些操作service生命周期关键方面并且给组件提供一个机制来绑定到serivce,如果合适。最重要的回调你应该覆盖的是:


onStartCommand() 系 统调这个方法当另一个组件,例如一个activity,请求启动这个service通过startService()。一旦这个方法执行,这个 service将启动并且无期限的运行在后台。如果你实现这个,那么停止service就是你的责任了当它的工作完成,通过调用stopSelf()或 stopService()。(如果你只希望提供绑定,你不需要实现这个方法)

onBind() 系 统调用这个方法当另一个组件希望绑定service(例如RPC),通过bindService()。在你这个方法的实现中,你必须提供一个客户使用的来 和这个service通信的接口,通过一个IBinder。你必须一直实现 这个函数,但如果你不希望允许绑定,那么你返回null。

onCreate() 系统调用这个方法当service第一次被创建,实现一次安装的步骤(在它调onStartCommand()和onBind()之前)。如果service已经在运行,那么这个方法不会调用。


onDestroy() 系统调用这个方法service不再使用将被摧毁。你的service应该实现这个来清理所有资源例如线程、注册的监听者、接收器等。这是service接收到的最后一个调用。


  如果一个组件启动一个service通过startService()(导致调用onStartCommand()),然后这个service维持运行直到它停止它自己通过stopSelf()或另一个组件停止它通过stopService()。

  如果一个组件调用bindService()来创建service(onStartCommand()不被调用),那么这个service当组件绑定它的时候运行。一量service被取消绑定从客户,系统销毁它。

  Android系统将强制停止一个service只有当内存很低并且它必须恢复系统资源为拥有用户焦点的activity。如果service 绑定到一个拥有用户焦点的activity,那么它不太可能被杀,如果service被声明为运行在前台(稍后讨论),那么 它将几乎永远不会被杀。否则,如果service启动,并且一直运行,那么 系统会降低它的位置在后台任何列表里随着时间,并且service将变得高度被杀--如果你的service一年非常,那么你必须设计它温柔的被系统重 启。如果系统杀死你的service,它重启它一量资源变得可利用(虽然这个也依赖于你从onStartCommand返回的值)。

Declaring a service in the manifest

  像很多activities(以及其它组件),你必须声明所有的services在你的应用程序manifest文件里。

  为了声明你的服务,加入<service>元素作为<application>元素的子元素。例如:

android  services 使用_Android

  有其它的属性你可以在<service>元素中来定义属性,例如启动service的权限和service运行在哪一个进程。

  就像一个activity,一个服务可以定义intent filters来允许其它组件激活服务使用隐含的intent。通过声明intent filters,任何其它应用程序的组件启动你的service如果你的service声明一个intent filter,匹配其它应用程序传递给startService()的intent。

  如果你计划只本地使用你的service(其它应用程序看不见),那么你不需要(也不应该)提供任何intent filters。没有任何intent filters,你必须启动这个service使用一个intent,显式的命名service类。

  额外的,你可以保证你的service是私有的对你的应用程序只有你包含android:exported属性并且设置它为"false"。这点非常有效,即使你的service提供intent filters。

Creating a Started Service

  一个开启的service是由另一个组件调用startService()开启,导致调用service的onStartCommand()方法。   当一个service忘却,它有一个第一期周期独立于启动它的组件并且永远久运行在后台,即使创建它的组件被摧毁。这样,service应当停止它自己当工作完成通过stopSelf()函数,或另一个组件能停止它通过stopService()函数。    一个应用程序组件例如一个activity可以开启service通过startService()并且传递一个Intent指定了service并且 包含任何数据给这个service来使用。Service接收这个Intent在onStartCommand()方法。   例如,假 设一个activity需要保存一些数据给一个在线的数据库。这个activity可以启动一个伙伴service并且传递给它将要被保存的数据,通过传 递一个intent给startService()。这个service接收intent在onStartCommand(),连接到网络,并且完成数据 库事务。当事务完成,这个service停止它自己并且被摧毁。   

警告 :一个service运行 在和应用程序的同一个进程的主线程,默认。所以,如果你的service完成高耗能或阻塞工作当用户和这个应用的activity交互的时候,这个 service会减慢activity的性能。为了避免影响应用程序性能,你应该开始一个新线程在这个service中。


     通常的,有两种类型你能继承来创建一个新service:

Service 这是所有service的基类型。当你继承这个类,你新建一个线程来做service的工作就显得非常重要,因为这个service使用你应用程序的主线程,默认,这将降低你应用程序正在运行的所有activity的性能。

IntentService 这是一个Service人基类型,使用一个工作线程来操作所有开始的请求,一次一个。这是最佳选择如果你不需要你的service同时处理多个请求。所有你需要做的是实现 onHandleIntent(),接收intent从每个 开启的请求以便让你做后台工作。



Extending the IntentService class 】   因为大多忘却的services不需要同时操作多个请求(会有多线程场景问题),可能的最好的方法是如果你实现你的service使用IntentService类。


  IntentService完成以下事情:   1、建立一个默认的工作线程执行所有的intent从onStartCommand()发来的,线程独立于你应用程序的主线程。   2、建立一个工作队列,一次传递一个intent给你的onHandleIntent()实现,这样你永远不用担心多线程。   3、停止service在所有的请求都处理完后,所以你永远不用调用stopSelf()。   4、提供默认的onBind()实现,即返回null的实现。   5、提供默认的onStartCommand()实现,发送intent给工作队列,然后发给你的onHandleIntent()实现。


  所有这些加一起就是你所需要做的就是实现onHandleIntent()来完成你的工作。(虽然,你也需要提供一些构造函数为service)


  下面是一个实现IntenService的例子:   


android  services 使用_java_02



  这就是你所需要的:一个构造函数和一个onHandleIntent()的实现。


  如果你也决定覆盖其它方法,例如onCreate()、onStartCommand()、或onDestroy(),保证调用父类实现,以便IntentService能合适的操作工作线程的生命期。


  例如,onStartCommand()必须返回默认的实现(这决定intent怎样被送到onHandleIntent())


android  services 使用_ui_03

  除了onHandleIntent()之外,惟一的方法你不需要调用的是onBind()(你只需要实现如果你的service允许绑定)。



Extending the Service class 】   就像你在前面看到的,使用IntentService让你的启动service变得非常简单。可是如果,你要求你的service实现多线程行为(不能使工作线程工作),那么你可以继承自Service类来操作这个intent。


  为了比较,下面的示例代码是一个Service的实现类,和上面的例子实现一样的功能使用IntentService。就是主产,对一个请求,它使用一个线程来袴工作并且一次只处理一个。


  <!-- 此处图略,可从SDK文档中查阅 -->   你会发现,有更多的工作和使用IntentService相比。   可是,因为你操作每一个调用onStartCommand()你自己,你可以同时处理多个请求。这不是这个例子做的事情,但是如果你需要的话,那么你可以建立一个线程为每一个请求并且立即运行它们(而不是等待前一个完成)。    注意onStartCommand()必须返回一个整数。这个整数是一个值,描述系统怎么继续service当系统杀死它的时候(就像上面讨论 的,IntentService默认帮你实现,虽然你能改变它)。从onStartCommand返回的值必须是下面中的一个:


START_NOT_STICKY 如果系统杀死service在onStartCommand返回后,不要重新创建service,除非有等待的intent是发送。这是最安全的选项来避免运行你的service当不需要和当你的应用程序可以简单的重启任何未完成的工作。

START_STICKY 如 果系统杀死service在onStartCommand()返回后,重新创建service并且调用onStartCommand(),但不重发送 intent。相反,系统调用onStartCommand()用空intent,除非有等待的intent来启动service,在这种情况下,这些 intents被传送。这适合中级选手(或相似服务)不在执行命令,但运行无期限和等待一个工作。

START_REDELIVER_INTENT 如 果系统杀死service在onStartCommand()之后,重新创建service并且调用 用onStartComand()用最后一个intent,任何等待的intent都将被依次传递。这对一些service合适,它们常常活跃于处理一个 工作应该被立即恢复,就像下载一个文件。



Starting a Service 】    你可以开始一个service从一个activity或其它应用程序组件通过传递一个Intent给startService()。Android系统 调用这个service的onStartCommand()方法并且传递它Intent。(你应该从不调用onStartCommand()直接)。   例如,一个activity能启动示例service在前一节的(helloservice)使用一个显式 的intent用startService();


android  services 使用_Android_04


  startService()方法立即返回并且Android系统调用service的onStartCommand()方法。如果service没有运行,系统调用onCreate(),然后调用onStartCommand()。


   如果service也没有提供绑定,用startService()发送的intent是惟一的通信方法在组件和服务。可是,如果你希望service 发送一个结果回去,那么客户开始这个service能创建一个PendingIntent为一个广播并且传递它给service。然后Service能利 用广播来传送结果。



Stopping a service 】    一个启动的service必须管理它自己的生命周期。也就是,这个系统不stop或摧毁除非系统要恢复内存,并且service一直运行在 onStartCommand()返回后。这样,service必须停止它自己通过stopSelf或另一个组件可以停止它通过 stopService()。   一旦请求停止用stopSelf或stopService(),系统摧毁这个service尽快。    可是,如果你的service在onStartCommand操作多个请求同时,那么 你不应该停止service当你已经完成一个请求,因为你可以已经接收到一个新的请求(在第一个请求后停止可能会终止第二个)。为了避免这个问题,你可以 使用stopSelf(int)来确保你的请求停止总是基于最近的请求。也就是,当你调用用stopSelf(int),你传递ID关于当前请求(ID传 递给onStartCommand)。那么如果service收到一个新的request在你能够调用stopSelf(int)之前,那么这个ID将不 会匹配并且service将不会停止 。   

警告 :你的应用程序停止它的服务当它完成工作这点非常 重要,为了避免浪费系统资源并且消耗电池。如果需要,其它组件可以停止service通过stopService()。即使你能绑定这个service, 你必须一直停止这个service你自己如果它收到一个onStartCommand()。


标签:service,onStartCommand,一个,应用程序,组件,intent,使用,services,android
From: https://blog.51cto.com/u_16034393/6886152

相关文章

  • ElasticSearch——使用备忘
    查询GEThttp://xxxxx:9200/user_list/_search 添加模板POSThttp://xxxxx:9200/user_list/_scripts/user_list_template{"script":{"lang":"mustache","source":"{\"query\":{\"bool\":{\&qu......
  • Android应用性能优化之分析工具
    Android应用性能优化之分析工具上一次记录了解决过度绘制的过程,这一次,想先弄清个概念性的东西,就是如何判断顺不顺畅?这东西其实最初我自己也觉得有点废话,用起来会卡就明显是不顺畅咯。但这东西就跟我很想吐槽很多应用一样,明明那么卡还放出来一样的道理。......
  • Android多线程及异步处理问题
    1、问题提出1)为何需要多线程?2)多线程如何实现?3)多线程机制的核心是啥?4)到底有多少种实现方式?2、问题分析1)究其为啥需要多线程的本质就是异步处理,直观一点说就是不要让用户感觉到“很卡”。eg:你点击按钮下载一首歌,......
  • Android多文件上传的原理
    android上面图片的上传可以用apache包里面的httpclient和MultipartEntity来上传图片,这种的上传方式的话由于都封装好了所以看不到HTTP协议里面具体是怎样上传的;其实图片的上传还可以用Java自带的HttpURLConnection来做上传处理,例如有一个PHP写的接收图片的POST接口http://localho......
  • 上百个Android开源项目分享
    上百个Android开源项目分享,希望对android开发有帮助。AndroidPDF阅读器http://sourceforge.net/projects/andpdf/files/个人记账工具OnMyMeanshttp://sourceforge.net/projects/onmymeans/developAndroid电池监控AndroidBatteryDoghttp://sourceforge.net/projects/a......
  • 使用Delphi编写DLL劫持内存补丁
    在有些破解程序时,不能暴力修改程序,修改后,程序就不能正常运行,因为很多程序启动时有自我的校验,但是当程序加载到内存后,在内存中修改相应的地方就可以达到破解的效果。那么怎样在不破坏程序的前提下,达到修改程序呢?当一个可执行文件运行时,Windows加载器将可执行模块映射到进程的地址......
  • Android开发者应该深入学习的10个…
    1.Android团队提供的示例项目 如果不是从学习AndroidSDK中提供的那些样例代码开始,可能没有更好的方法来掌握在Android这个框架上开发。由Android的核心开发团队提供了15个优秀的示例项目,包含了游戏、图像处理、时间显示、开始菜单快捷方式等。 地址:http://code.google.com/p/......
  • Android JNI 编写方法
    JavaNativeInterface(JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI是本地编程接口,它使得在Java虚拟机(VM)内部运行的Java代码能够与用其它编程语言(如C、C++和汇编语言)编写的应用程序和库进行交互操作。1.Java方式实现JNI,函数路径匹配......
  • Android图形系统之Surface、Surfac…
    1、SurfaceSurfaceextendsObjectimplementsParcelableClassOverviewHandleontoarawbufferthatisbeingmanagedbythescreencompositor.简单翻译:Surface是原始图像缓冲区(rawbuffer)的一个句柄,而原始图像缓冲区是由屏幕图像合成器(screencompositor)管理的。java.lan......
  • android与PC,C#与Java 利用protob…
    protobuf是什么? Protocolbuffers是一种编码方法构造的一种有效而可扩展的格式的数据。谷歌使用其内部几乎RPC协议和文件格式的所有协议缓冲区。参考文档http://code.google.com/intl/zh-CN/apis/protocolbuffers/docs/overview.html  API的 参考文档 ......