安卓服务Service
- 格式:ppt
- 大小:385.50 KB
- 文档页数:17
安卓的四⼤组件Android四⼤基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver⼴播接收器。
⼀:了解四⼤基本组件Activity :应⽤程序中,⼀个Activity通常就是⼀个单独的屏幕,它上⾯可以显⽰⼀些控件也可以监听并处理⽤户的事件做出响应。
Activity之间通过Intent进⾏通信。
在Intent 的描述结构中,有两个最重要的部分:动作和动作对应的数据。
典型的动作类型有:M AIN(activity的门户)、VIEW、PICK、EDIT 等。
⽽动作对应的数据则以URI 的形式进⾏表⽰。
例如:要查看⼀个⼈的联系⽅式,你需要创建⼀个动作类型为VIEW 的intent,以及⼀个表⽰这个⼈的URI。
与之有关系的⼀个类叫IntentFilter。
相对于intent 是⼀个有效的做某事的请求,⼀个intentfilter 则⽤于描述⼀个activity(或者IntentReceiver)能够操作哪些intent。
⼀个activity 如果要显⽰⼀个⼈的联系⽅式时,需要声明⼀个IntentFilter,这个IntentFilter 要知道怎么去处理VIEW 动作和表⽰⼀个⼈的URI。
IntentFilter 需要在AndroidManifest.xml 中定义。
通过解析各种intent,从⼀个屏幕导航到另⼀个屏幕是很简单的。
当向前导航时,activity 将会调⽤startActivity(Intent myIntent)⽅法。
然后,系统会在所有安装的应⽤程序中定义的IntentFilter 中查找,找到最匹配myIntent 的Intent 对应的activity。
新的activity 接收到myIntent 的通知后,开始运⾏。
当startActivity ⽅法被调⽤将触发解析myIntent 的动作,这个机制提供了两个关键好处:A、Activities 能够重复利⽤从其它组件中以Intent 的形式产⽣的⼀个请求;B、Activities 可以在任何时候被⼀个具有相同IntentFilter 的新的Activity 取代。
service工作原理service是Android平台上的一种组件,用于在后台执行长时间运行的操作或处理来自其他组件的请求。
它可以在应用程序的主线程之外运行,因此不会阻塞用户界面(UI)的操作。
Service运行在相对独立的进程中,因此即使在应用程序被销毁或不可见时,它仍然可以继续运行。
Service可以分为两种类型:启动式和绑定式。
启动式服务通过startService()方法来启动,不与调用者之间建立直接的链接。
它们在后台独立运行,无需依附于调用者的生命周期。
绑定式服务则通过bindService()方法绑定到调用者,与调用者之间建立一对一的链接。
这种服务的生命周期与调用者的生命周期相关联。
Service的工作原理如下:1. 在应用程序中创建一个继承自Service基类的子类,并重写其onCreate()、onStartCommand()和onDestroy()方法(对于绑定式服务,还需重写onBind()和onUnbind())。
2. 在应用程序的清单文件中声明该Service组件,以便系统可以识别并启动它。
可以通过设置属性android:exported为true或false来指定Service是否可以被其他应用程序访问。
3. 在需要启动或绑定Service的地方,调用startService()或bindService()方法。
通过Intent可以传递操作和数据给Service。
4. 如果是启动式服务,调用者与Service之间没有直接的链接,Service会在后台独立运行。
它会在调用startService()方法后立即调用onStartCommand()方法,在这个方法里可以执行耗时的操作。
5. 如果是绑定式服务,调用者与Service建立起一对一的链接。
调用bindService()方法后,会触发Service的onBind()方法,在这个方法里可以返回一个提供给调用者进行交互的Binder对象。
Android 应用程序的基本组件Android 操作系统是目前世界上最流行的移动操作系统之一。
它提供了广泛的应用程序开发工具和框架,使开发者能够轻松地创建出丰富多样的应用程序。
而这些应用程序的基础是由一些基本组件构成的。
本文将介绍 Android 应用程序的基本组件,包括活动(Activity)、服务(Service)、广播接收器(Broadcast Receiver)和内容提供器(Content Provider)。
活动(Activity)是 Android 应用程序的核心组件之一。
它代表了用户与应用程序之间的交互界面。
每个 Android 应用程序都至少包含一个活动,而活动可以包含多个界面元素,例如按钮、文本框、图像等。
活动通过布局文件定义了界面的外观和布局,通过代码来处理用户的操作和响应。
活动之间可以通过意图(Intent)来进行切换和通信,从而实现应用程序之间的流转和交互。
服务(Service)是在后台运行的组件,它可以在没有用户界面的情况下执行长时间运行的操作。
服务通常用于执行一些独立的任务,例如播放音乐、下载文件等。
通过在应用程序中创建服务,开发者可以在用户不可见的情况下执行一些必要的操作,并提供持久性的后台功能。
广播接收器(Broadcast Receiver)是一种用于接收系统广播消息的组件。
广播是 Android 系统中不同组件之间进行通信的一种方式,例如设备启动完成、电池电量变化等。
通过注册一个广播接收器,开发者可以监听和响应系统广播消息,并执行相应的操作。
广播接收器可以用于实现各种功能,例如接收短信、接收网络状态变化等。
内容提供器(Content Provider)是 Android 中用于共享数据的一种机制。
内容提供器允许一个应用程序将其数据暴露给其他应用程序。
通过内容提供器,不同的应用程序可以相互访问和共享数据,实现数据的交互和共用。
例如,系统提供的联系人数据库就是通过内容提供器来共享和访问联系人数据的。
Service详解⼀什么是Service⼀个Service是没有界⾯且能长时间运⾏于后台的应⽤组件.其它应⽤的组件可以启动⼀个服务运⾏于后台,即使⽤户切换到另⼀个应⽤也会继续运⾏.另外,⼀个组件可以绑定到⼀个service来进⾏交互,即使这个交互是进程间通讯也没问题.例如,⼀个aservice可能处理⽹络事物,播放⾳乐,执⾏⽂件I/O,或与⼀个内容提供者交互,所有这些都在后台进⾏.⼀个service本质上可有两种表现形式: 尽管这个⽂档是把这两种service分开讲的,但你的service可以在这两种⽅式下⼯作.—它可以是started(⽆限期运⾏)同时也允许绑定.唯⼀的简单问题是你是否实现了⼀对回调⽅法:onStartCommand()允许组件启动它并且onBind()允许绑定.不论你是应⽤是否启动,或绑定到⼀个服务或两者都做了,任何应⽤组件都可以使⽤service(即使从另⼀个应⽤),跟任何组件都可以使⽤activity⼀样—通过⼀个Intent启动它.然⽽,你可以在manifest⽂件中声明服务为私有,并且阻⽌另外的应⽤访问它.这在讲如何于manifest⽂件中声明service时会详细讲解. 注意:⼀个service是运⾏在它所在进程的主线程中的—service不会创建它⾃⼰的thread也不会运⾏于单独的进程(除⾮你另外指定).这表⽰,如果你的service想做⼀些狂耗CPU的⼯作或阻塞型的操作(⽐如MP3播放或⽹络通讯),你必须在service中创建⼀个新的线程来做那些⼯作.通过使⽤⼀个分离的线程,你将减少"应⽤没有反应"(ANR)错误并且应⽤的主线程可以保持activity对⽤户操作的快速反应.基础你应使⽤⼀个service还是线程? ⼀个service是⼀个在⽤户不与你的应⽤交互时依然可以运⾏于后台的简单组件.所以,只有你需要这样做时才创建⼀个service. 如果你需要执⾏的⼯作不在主线程中,但是只有⽤户在与你的应⽤交互时才进⾏,那么你可能应该创建⼀个新的线程⽽不是⼀个service.例如,如果你想播放⼀些⾳乐,但是只在你的activity运⾏时才播放,你应该在onCreate()中创建⼀个线程,在onStart()运⾏这个线程,然后在onStop()中停⽌它.也可以考虑使⽤AsyncTask或HandlerThread,来代替传统的线程类. 记住,如果你使⽤了service,它默认会固定运⾏于你的应⽤的主线程,所以你应该在其中创建⼀个线程来执⾏耗时或阻塞的操作要创建⼀个service,你必须创建⼀个Service类(或某个已存在的⼦类)的⼦类.在你的实现中,你应覆写⼀些处理有关service⽣命期的关键⽅⾯的回调⽅法并且提供⼀个能让组件绑定到service的机制(如果需要).你应覆写的最重要的回调⽅法是: 如果⼀个组件通过调⽤startService()启动⼀个service(最终导致onStartCommand()被调⽤),之后service会保持运⾏,直到它通过stopSelf()停⽌⾃⼰或另外的组件调⽤stopService()停⽌它. 如果⼀个组件调⽤bindService()来创建service(onStartCommand()不会被调⽤),那么service只是运⾏在绑定期间.⼀旦service从所有的客户端解除绑定,系统就会杀了它. Android系统只在内存很少并且必须为具有⽤户焦点的actvity釋放资源时才会强制停⽌⼀个service.如果service是绑定到具有⽤户焦点的activity上,那么它很难被杀死,并且如果service被声明为运⾏于前台(后⾯将讨论),那么它将永不被杀死,除⾮,如果这个service启动并且长期运⾏,那么系统将会降低它在后台任务超时列表中的位置然后这个将变成⾼度易被杀对象—如果你的service被启动,那么它必须被设计为能优雅地处理被系统重启的操作.如果系统杀死了你的service,它会在资源重新可⽤时⽴马重启它(但是依赖于你在onStartCommand()中的返回值).⼆如何创建⼀个Service在manifest中声明⼀个service 跟activity以及其它组件⼀样,你必须在你的应⽤的manifest⽂件中声明所有的service们. 要声明你的service,添加⼀个<service>元素作为<application>元素的⼉⼦.例如:[java]01. <manifest ... >02. ...03. <application ... >04. <service android:name=".ExampleService" />05. ...06. </application>07. </manifest> 有许多属性你可以包含在<service>元素中,⽐如启动service的权限和service运⾏所在的进程.android:name属性是哇⼀必须的—它指定了service类的名字.⼀旦你发布了你的应⽤,你不应再改变这个名字,因为如果你改了,你可能使⼀些通过明确的intent来引⽤你的service的功能⽆法运⾏. 就像⼀个activity,⼀个service可以定义intent过滤器来使得其它组件使⽤明确的intent调⽤⾃⼰.通过声明intent过滤器,你设备上的任意应⽤中的组件都可以通过给startService()传递匹配的intent来启动你的sevice. 如果你打算只在本应⽤内使⽤⾃⼰的service,那么你不需指定任何intent过滤器.不使⽤intent过滤器,你必须使⽤⼀个明确指定service的类名的intent来启动你的service. 另外,你也可以通过包含android:exported属性,并指定其值为”false”来保证你的service是私有的.即使你的service使⽤了intent过滤器,也会起作⽤.创建⼀个"启动的"Service 针对Android1.6或更早的版本: 如果你创建的应⽤是针对Android1.6或更早版本的,你需要实现onStart()⽽不是onStartCommand()(在Android2.0中,onStart()被废弃代替之以onStartCommand()). 更多关于如何兼容2.0之前版本的知识,请看onStartCommand()⽂档. ⼀个启动的service,在被其它组件调⽤startService()来启动时,会导致service的onStartCommand()⽅法被调⽤. 当⼀个service被启动后,它的⽣命期就不再依赖于启动它的组件并且可以独⽴运⾏于后台,即使启动它的组件死翘翘了.所以,service应该⼯作完成后调⽤stopSelf()⾃⼰停⽌掉,或者其它组件也可以调⽤stopService()停⽌service. ⼀个应⽤组件,⽐如⼀个activity可以通过调⽤startService()启动service同时传递⼀个指定service和service所⽤的数据的Intent,service在⽅法onStartCommand()中接收这个Intent.事物完成后,service停⽌⾃⼰然后被销毁. ⼩⼼:service默认运⾏在声明它的应⽤进程的主线程中.所以,如果你的service执⾏密集运算或阻塞操作并且与跟⽤户交互的activity位于相同的应⽤中,这个service将会拉低activity的性能.要避免影响应⽤的性能,你必须在service中启动⼀个线程. 传统上,有两个类你可以从它派⽣来创建"启动的"service:从IntentService类派⽣ 因为⼤多数"启动的"service不需要同时处理多个请求,可能从IntentService实现你的service是最好的选择.IntentService做了以下⼯作: 以上实现使得你可以仅仅实现onHandleIntent()来做要做的⼯作即可.(当然,你还是要实现⼀个⼩⼩的构造函数).下⾯是⼀个实现IntentService的例⼦:01. public class HelloIntentService extends IntentService {02.03. /**04. * ⼀个构造函数是必须的,并且你必须调⽤⽗类的IntentService(String)以传⼊⼯作线程的名字.05. */06. public HelloIntentService() {07. super("HelloIntentService");08. }09.10. /**11. * IntentService在默认的⼯作线程中调⽤这个⽅法<p> *当这个⽅法返回后,IntentService停⽌服务,如果能停⽌的话.12. */13. @Override14. protected void onHandleIntent(Intent intent) {15. // Normally we would do some work here, like download a file.16. // For our sample, we just sleep for 5 seconds.17. long endTime = System.currentTimeMillis() + 5*1000;18. while (System.currentTimeMillis() < endTime) {19. synchronized (this) {20. try {21. wait(endTime - System.currentTimeMillis());22. } catch (Exception e) {23. }24. }25. }26. }27. }</p> 以上就是你所有需要做的:⼀个构造函数和⼀个onHandleIntent()的实现. 如果你决定重写其它的⽅法,⽐如onCreate(),onStartCommand(),oronDestroy(),要保证调⽤⽗类的对应实现,这样IntentService才能正确地处理⼯作线程的⽣命期.⽐如,onStartCommand()必须返回默认的实现(其中实现了intent被传送到onHandleIntent()的逻辑):[java]01. @Override02. public int onStartCommand(Intent intent, int flags, int startId) {03. Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();04. return super.onStartCommand(intent,flags,startId);05. } 除onHandleIntent()外,唯⼀不需调⽤⽗类实现的⽅法是onBind()(但是你只需在你的service允许绑定时才实现它). 在下⼀节,你将看到同样的service类,从类Service派⽣时是如何实现的.这需要写更多的代码,但是当你需要处理同时发⽣的请求时(⾮序列化)这就是合适的做法了使⽤类IntentService使得你实现⼀个"开始的"service⾮常容易.然⽽,如果你需要你的service以多线程⽅式执⾏(⽽不是使⽤⼯作队列),那么你需要从类Service派⽣来处理每个intent. 相⽐之下,下⾯的例⼦从类Service派⽣并实现了与上⾯使⽤IntentService例⼦完全相同的⼯作.也就是在⼀个线程中序列化的处理每个"开始"请求.01. <span style="font-size:18px;">public class HelloService extends Service {02. private Looper mServiceLooper;03. private ServiceHandler mServiceHandler;04.05. // 处理从线程收到的消息们06. private final class ServiceHandler extends Handler {07. public ServiceHandler(Looper looper) {08. super(looper);09. }10. @Override11. public void handleMessage(Message msg) {12. // 通常我们在这⾥做⼀些⼯作⽐如下载⼀个⽂件13. // 在我们的例⼦中,仅仅是睡5秒钟.14. long endTime = System.currentTimeMillis() + 5*1000;15. while (System.currentTimeMillis() < endTime) {16. synchronized (this) {17. try {18. wait(endTime - System.currentTimeMillis());19. } catch (Exception e) {20. }21. }22. }23. // 使⽤startId停⽌服务,从⽽使我们不会在处理24. // 另⼀个⼯作的中间停⽌service25. stopSelf(msg.arg1);26. }27. }28.29. @Override30. public void onCreate() {31. // 启动运⾏service的线程.注意我创建了⼀个32. // 分离的线程,因为service通常都是在进程的33. // 主线程中运⾏,但我们不想让主线程阻塞.我们还把新线程34. // 搞成后台级的优先级,从⽽减少对UI线程(主线程的影响).35. HandlerThread thread = new HandlerThread("ServiceStartArguments",36. Process.THREAD_PRIORITY_BACKGROUND);37. thread.start();38.39. // Get the HandlerThread's Looper and use it for our Handler40. mServiceLooper = thread.getLooper();41. mServiceHandler = new ServiceHandler(mServiceLooper);42. }43.44. @Override45. public int onStartCommand(Intent intent, int flags, int startId) {46. Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();47.48. // 对于每个开始请求,发送⼀消息来开始⼀次⼯作,并且把49. // start ID也传过去,所以当完成⼀个⼯作时,我们才知道要停⽌哪个请求.50. Message msg = mServiceHandler.obtainMessage();51. msg.arg1 = startId;52. mServiceHandler.sendMessage(msg);53.54. // 如果我们在这⾥返回后被被杀死了,重启之.55. return START_STICKY;56. }57.58. @Override59. public IBinder onBind(Intent intent) {60. // We don't provide binding, so return null61. return null;62. }63.64. @Override65. public void onDestroy() {66. Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();67. }68. }69. </span> 如你所见,要做的⼯作⽐使⽤IntentService时多⼀些. 然⽽,因为你⾃⼰处理每次对onStartCommand()的调⽤,你可以同时执⾏多个请求.这个例⼦并没有那样做,但是如果那是你所需要的,那么你可以为每个请求创建⼀个新的线程并且⽴即运⾏它们(⽽不是等待上⼀个请求完成). 注意⽅法onStartCommand()必须返回⼀个整数.这个整数描述了在系统杀死它的事件中系统如何继续这个服务(如前⾯所述,IntentService的默认实现为你处理这些,当然你也能够去改写它).onStartCommand()也返回值必须是下⾯常量之⼀:开始⼀个Service 你可以从⼀个activity或从其它应⽤的组件通过传递⼀个Intent(指定了要启动的服务)给startService()启动⼀个服务.Android系统然后调⽤service的onStartCommand()⽅法并且把Intent传递给它.(你永远不能直接调⽤onStartCommand().) 例如,⼀个activity可以在调⽤startService()时使⽤⼀个明确的intent开始前⽂的例⼦中的service(HelloSevice):Intentintent = new Intent(this, HelloService.class);startService(intent); startService()⽅法会⽴即返回然后Android系统调⽤service的onStartCommand()⽅法.但是如果service尚没有运⾏,系统会先调⽤onCreate(),然后调⽤onStartCommand(). 如果service没有提供绑定功能,传给startService()的intent是应⽤组件与service之间唯⼀的通讯⽅式.然⽽,如果你希望service回发⼀个结果,那么启动这个service的客户端可以创建⼀个⽤于⼴播(使⽤getBroadcast())的PendingIntent然后放在intent中传给service,service然后就可以使⽤⼴播来回送结果. 不同的启动请求导致对service的onStartCommand()的不同调⽤,但停⽌service的请求只有⼀个(使⽤stopSelf()或stopService()).停⽌⼀个service ⼀个"启动的"service必须管理其⾃⼰的⽣命期.这表⽰,系统不会停⽌或销毁这种service,除⾮内存不够⽤了并且service在onStartCommand()返回后会继续运⾏.所以,service必须调⽤stopSelf()停⽌⾃⼰或由另⼀个组件调⽤stopService()来停⽌它. ⼀旦通过stopSelf()或stopService()发出了停⽌请求,系统就会尽可能快地销毁service. 然⽽,如果你的service同时处理多个对onStartCommand()的请求,那么你不应在处理完⼀个请求之后就停⽌service,因为你可能已经⼜收到了新的启动请求(在第个完成后停⽌将会结束掉第⼆个).要避免这个问题,你可以使⽤stopSelf(int)来保证你的停⽌请求对应于你最近的开始请求.也就是,当你调⽤stopSelf(int)时,你传递开始请求的ID(传递给onStartCommand()的startId)给service,如果service在你调⽤stopSelf(int)之前收到⼀了个新的开始请求,发现ID不同,于是service将不会停⽌. 注意:你的应⽤在完成⼯作后停⽌它所有的service是⾮常重要的.这可以避免浪费系统资源和消耗电量.如果需要,其它的组件可以调⽤stopService()停⽌service.即使你为service启⽤了绑定,你也必须⾃⼰停⽌service,甚⾄它收到了对onStartCommand()的调⽤也这样.创建⼀个绑定的Service ⼀个绑定的service是允许应⽤的组件通过调⽤bindService()来绑定它以创建⼀个能长期存在的连接(并且⼀般不允许组件调⽤startService()来启动它). 当你的activity或其它组件想与service交互或你的应⽤想基于IPC的向其它应⽤提供功能时,你应该创建⼀个绑定的service. 要创建⼀个绑定的service,你必须实现回调⽅法onBind(),还要在其中返回⼀个IBinder,这个IBinder定义了与service通讯的接⼝.其它应⽤组件就可以在之后调⽤bindService()来接收这个接⼝并开始调⽤service的⽅法.service只在有应⽤组件绑定到它时才活着,所以当没有组件绑定到它时,系统就会宰了它(你不需去停⽌⼀个绑定的service,跟⽤onStartCommand()启动的service不⼀样). 要创建⼀个绑定的service,⾸先要做的就是定义客户端如何与service通讯的接⼝.这个接⼝必须是IBinder的⼀个实现,并且必须被回调⽅法onBind()返回.⼀旦客户端接收到IBinder,它就可以开始与service进⾏交互. 多个客户端可以⼀起绑定到⼀个service.当⼀个客户端完成与service的交互,它调⽤unbindService()来解除绑定.⼀旦不再有任何客户端绑定到service,系统就宰了这个service. 有很多⽅法来实现⼀个绑定的service并且这些实现要⽐"开始的"service难懂得多.发送通知给⽤户 ⼀旦开始运⾏,⼀个service可以通过Toast通知或状态栏通来通知⽤户⼀些事件. ⼀个toast通知是⼀个出现在当前窗⼝表⾯上并过⼀会就消失的消息.当⼀个状态栏通知提供⼀个带有消息的图标到状态栏,⽤就可以先定它来执⾏⼀些动作(⽐如启动⼀个activity). 通常,⼀个状态栏通知是当⼀些后台⼯作(⽐如⼀个⽂件下载完成了)完成后通知⽤户可以对它进⾏动作的最佳⽅式.当⽤户选择这个通知时,它可以开始⼀个activity(⽐如可以查看下载的⽂件).在前台运⾏Service ⼀个前台的service是被⽤户强烈关注的从⽽不会在内存低时被系统杀死.前台service必须在状态栏上提供⼀个通知,这个通知被放在"正在进⾏"区域中,这表⽰这个通知不能被解除,除⾮服务停⽌了或者从前台移除了. 例如,⼀个从service播放⾳乐的⾳乐播放器,应被设置为前台运⾏,因为⽤户会明确地注意它的运⾏.在状态栏中的通知可能会显⽰当前的歌曲并且允许⽤户启动⼀个activity来与⾳乐播放器交互.[java]01. Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),02. System.currentTimeMillis());03. Intent notificationIntent = new Intent(this, ExampleActivity.class);04. PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);05. notification.setLatestEventInfo(this, getText(R.string.notification_title),06. getText(R.string.notification_message), pendingIntent);07. startForeground(ONGOING_NOTIFICATION, notification); 要请求你的service运⾏于前台,调⽤startForeground().此⽅法有两个参数:⼀个整数唯⼀的标识⼀个通知,和这个⽤于状态栏的通知,例如: 要从前台移除service,调⽤stopForeground().这个⽅法有boolean型参数,表明是否也从状态栏删除对应的通知.这个⽅法不会停掉service.然⽽,如果你停⽌了正在前台运⾏的service,这个通知也会被删除. 注意:⽅法startForeground()和⽅法stopForeground()是从Android2.0 (API Level 5)引⼊的.为了在早期版本是于前台运⾏你的service,你必须使⽤以前的那个setForeground()⽅法—见startForeground()的API⽂档查看如何提供与旧版本的兼容性.管理Service的⽣命期 ⼀个service的⽣命期⽐⼀个activity要简单得多.然⽽,你依然需要密切关注你的service是如何被创建⼜是如何被销毁的,因为⼀个service可以运⾏于后台⽽⽤户看不到它. service的⽣命期—从它被创建到它被销毁—有两条路可⾛: 这两条路并不是完全分离的.也就是,你是可以绑定到⽤startService()启动的service的.例如,⼀个后台⾳乐service在通过传⼊指明要播放的⾳乐的intent来调⽤startService()后启动.之后,当⽤户想对播放器进⾏⼀些操作或要获取当前歌曲的信息时,⼀个activity可以通过调⽤bindService()绑定到service.在此情况下,stopService()或stopSelf()不会真正的停⽌service,除⾮所有的客户端都取消绑定了.实现⽣命期回调⽅法 就像activity,service也具有⽣命期回调⽅法,⽤它们你可以监视service的状态的变化并且在合适的时机做⼀些⼯作.下⾯的框架代码演⽰了每个⽣命期⽅法的实现:[java]01. public class ExampleService extends Service {02. int mStartMode; // 表明在service被杀后的⾏为03. IBinder mBinder; // 客户端绑定到的接⼝04. boolean mAllowRebind; // 表明onRebind是否应被使⽤05.06. @Override07. public void onCreate() {08. // The service is being created09. }10. @Override11. public int onStartCommand(Intent intent, int flags, int startId) {12. // service 正在启动,在调⽤startService()期间被调⽤13. return mStartMode;14. }15. @Override16. public IBinder onBind(Intent intent) {17. // ⼀个客户端通过bindService()绑定到这个service18. return mBinder;19. }20. @Override21. public boolean onUnbind(Intent intent) {22. // 所有的客户端使⽤unbindService()解除了绑定23. return mAllowRebind;24. }25. @Override26. public void onRebind(Intent intent) {27. // ⼀个客户端在调⽤onUnbind()之后,正使⽤bindService()绑定到service28. }29. @Override30. public void onDestroy() {31. // service不再被使⽤并将被销毁32. }33. }注:不像activity的⽣命期回调⽅法们,你不需要调⽤⽗类的相应实现.图 2.service的⽣命期.左图显⽰了⽤startService()创建的service的⽣命期,右图显⽰了⽤bindService()创建的service的⽣命期.通过实现这些⽅法们,你可以监视service⽣命期的两个嵌套循环:注:尽管⼀个"启动的"service在调⽤stopSelf()或stopService()时结束,但并没有单独的回调对应这些停⽌⽅法(没有类似于onStop()的回调).所以,除⾮service被绑定到⼀个客户端,系统就会在停⽌时销毁service—onDestroy()是唯⼀收到的回调.图 2演⽰了service的典型回调.尽管图⽰分开了通过startService()和bindService()创建的service,但记住任何service,不管它是怎样启动的,都是可能允许绑定的.所以⼀个从onStartCommand()启动的service(客户端调⽤了startService())仍可以接收onBind()调⽤(当客户端调⽤bindService()时).。
android systemservice类理解Android SystemServer类是Android系统中的一个重要组件,负责管理系统中的各种服务和功能模块。
了解SystemServer类的工作原理和功能对于理解Android系统的整体架构非常重要。
本文将深入探讨Android SystemServer类的相关知识,帮助读者更好地理解和掌握Android系统的工作原理。
SystemServer类是Android系统启动过程中的一个关键角色,它在系统启动时被创建并负责启动和管理系统中的各种服务。
SystemServer类的主要作用包括但不限于以下几个方面:1. 启动系统服务:SystemServer类负责启动系统中的各种服务,包括ActivityManagerService、PowerManagerService、PackageManagerService等。
这些系统服务是Android系统正常运行的基础,SystemServer类通过启动这些服务确保系统的正常运行。
2. 管理系统功能模块:SystemServer类还负责管理系统中的各种功能模块,包括输入管理、窗口管理、通信管理等。
它通过调用相应的模块来管理系统的各项功能,确保系统的稳定运行。
3. 处理系统启动流程:SystemServer类在系统启动时被创建并启动,它会依次启动系统中的各个服务和功能模块,完成系统的初始化和准备工作。
系统启动的过程中,SystemServer类扮演着重要的角色。
了解SystemServer类的工作原理和功能有助于我们更好地理解Android系统的整体架构。
在Android系统的启动过程中,SystemServer类起着至关重要的作用,它负责启动系统中的各种服务和功能模块,确保系统的正常运行。
SystemServer类的工作原理可以总结为以下几个步骤:1. 创建SystemServer实例:系统启动时,SystemServer类的实例会被创建并初始化。
转Androidservice启动篇之startForegroundService本⽂转⾃:前⾔:在官⽅⽂档中有这样⼀段话:Android 8.0 有⼀项复杂功能;系统不允许后台应⽤创建后台服务。
因此,Android 8.0 引⼊了⼀种全新的⽅法,即Context.startForegroundService(),以在前台启动新服务。
在系统创建服务后,应⽤有五秒的时间来调⽤该服务的⽅法以显⽰新服务的⽤户可见通知。
如果应⽤在此时间限制内未调⽤,则系统将停⽌服务并声明此应⽤为。
中对整个start 过程进⾏了梳理,其中startService 和startForegroundService 最终调⽤调⽤的接⼝时⼀样的,只是其中要求foreground 启动service。
基于上⼀篇博⽂,这⾥对于前台服务进⾏详细的解析。
1 startServiceLocked流程同,最终调⽤接⼝为ActivieServices 中startServiceLocked:stActivity = SystemClock.uptimeMillis();r.startRequested = true;r.delayedStop = false;r.fgRequired = fgRequired;r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),service, neededGrants, callingUid));初始化ServiceRecord,其中fgRequired 为true。
然后将需要start 的service 添加到pendingStarts 中,中知道最后会在bringUpServiceLocked的函数中进⾏最终启动。
对于前台服务 sendServiceArgsLocked() 函数中会拉起⼀个timeout,时长为 5 秒,也就是说5s 后会抛出ANR的异常。
安卓的四大框架xx年xx月xx日CATALOGUE目录•安卓简介•安卓的四大框架概述•活动(Activity)•服务(Service)•广播接收器(Broadcast Receiver)•内容提供者(Content Provider)01安卓简介安卓是一种基于Linux的开放源代码移动设备操作系统。
它主要用于智能手机、平板电脑等移动设备。
安卓系统由谷歌公司进行维护和更新,全球市场份额位居首位。
安卓的定义安卓的发展史2003年,Andy Rubin创立安卓公司。
2007年,安卓开发者使用安卓开源项目发布了第一个操作系统。
2005年,谷歌收购安卓公司并将其作为开源项目。
2011年,安卓市场份额超过塞班成为全球第一大智能手机操作系统。
安卓系统的特点安卓系统是开放源代码的,这使得开发者可以自由地访问源代码并自由地使用、修改和分发它。
开放源代码免费和开源定制性高支持各种设备安卓系统是免费的,并且它的源代码可以被任何一个人查看、使用、修改和分发。
安卓系统允许用户和开发者高度定制手机,可以随意更换操作系统组件和应用程序。
安卓系统支持各种设备,包括智能手机、平板电脑、智能手表、电视盒子等。
02安卓的四大框架概述活动(Activity)它是一个应用程序当前所执行的操作,并且是应用程序中最重要的组件之一。
活动是用户界面的基础,是应用程序与用户进行交互的组件。
活动保存了应用程序的状态,并且提供了应用程序与用户交互的接口。
服务(Service)服务是在后台运行且不与用户界面交互的组件。
它可以在用户界面和后台任务之间提供一个桥梁,使应用程序可以在后台执行长时间运行的操作,而无需与用户界面进行交互。
服务可以在应用程序的任何地方使用,并且可以在任何时候启动和停止。
广播接收器(Broadcast Receiver)广播接收器是一个用于接收来自系统或其他应用程序的广播消息的组件。
它可以在应用程序不活动时接收广播,然后在接收到广播时执行相应的操作。
android systemservice类理解在Android中,`SystemService`(系统服务)是一种提供系统级功能的组件。
它允许应用程序与系统的核心功能进行交互,而无需了解底层实现细节。
系统服务是一种将设备功能暴露给应用程序的机制,使应用程序能够访问设备硬件、系统资源和其他关键功能。
系统服务是由Android操作系统管理和提供的,应用程序可以通过系统服务与这些功能进行通信。
一些常见的系统服务包括:1. ActivityManager: 管理应用程序的生命周期和任务栈。
2. PackageManager: 管理应用程序的安装、卸载和信息查询。
3. WindowManager: 管理窗口和界面元素。
4. NotificationManager: 管理通知。
5. TelephonyManager: 提供与电话相关的信息和功能。
6. ConnectivityManager: 管理网络连接。
7. LocationManager: 提供地理位置信息。
8. PowerManager: 管理设备的电源状态。
9. AudioManager: 控制音频设置和管理音频。
10. SensorManager: 管理设备上的传感器。
11. Vibrator: 控制设备的振动。
这些系统服务是通过`Context`对象的`getSystemService()`方法获得的。
例如,要获取`AudioManager`:```javaAudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);```这里的`Context`是Android应用程序的一个关键组件,提供了应用程序的全局信息和对Android环境的访问权限。
系统服务的使用使应用程序能够访问设备功能,而无需实现这些功能的底层逻辑。
这样,Android提供了一种标准的接口,允许应用程序开发者专注于其应用的特定功能,而不必处理底层的硬件和系统细节。
开始介绍之前,先看一下本例的界面:Android远程Service调用简介:远程Service调用,是Android系统为了提供进程间通信而提供的轻量级实现方式,这种方式采用一种称为远程进程调用技术来实现,英文名全称是Remote Procedure Call,即RPC。
RPC简介:远程进程调用是指在一个进程里,调用另外一个进程里的服务。
Android通过接口定义语言来生成两个进程间的访问代码。
接口定义语言(Android Interface Definition Language,即AIDL)是Android系统的一种接口描述语言,Android编译器可以将AIDL文件编译成一段JA V A代码,生成相对的接口。
下面来详细介绍下如何通过RPC机制来达到远程进程调用的目的和步骤。
第一,我们要先弄清楚这是怎么样的一个流程。
用通俗点语言来说,打个例子:比如公司A提供A服务,并且这种服务是对外开放的,也就是其他公司或者个人都可以通过某种方式来使用这种服务,公司B想要使用A公司的A服务,就以通过公司A编制的一种形式来使用它。
用图来表示就是:公司B通过公司A的某种形式来使用公司A提供的服务A现在,我们可以说,进程B可以通过进程A提供的某种形式来使用进程A的服务A。
这个过程就是RPC。
了解基本概念之后,我们可以开始进行RPC的实现步骤。
下面我们分点来说明实现RPC 的步骤。
第一、创建AIDL文件。
这个文件和普通的JA V A文件差不多,只不过后缀名是.aidl。
这个文件相当于一个接口,里面要声明一些你想对外提供服务的方法,也就是你要对外暴露的方法。
注意,这个文件里,除了JA V A基本类型和String,List,Map和Charquene类型不需要引入相应的包外,其他的都要引入包。
例如我们创建一个IPerson.aidl文件,里面只声明了一个方法display():package com.test.service;interface IPersonaidl {String display();//该接口里面所有的方法都应该是你想对外暴露的}第二、创建完AIDL文件后,刷新项目,会发现在gen目录对应的目录下会生成一个IPerson.java接口文件,打开该文件,会发现你在aidl文件里面定义的display()方法,不过没有实现。
调用service服务方法调用service服务•介绍•方法一:直接调用•方法二:使用Intent启动Service•方法三:使用Messenger进行进程间通信•方法四:使用AIDL实现跨进程通信•总结介绍在Android开发中,我们常常需要使用service服务来完成一些后台任务。
调用service服务可以让我们的应用变得更加强大和灵活。
本文将介绍几种常用的调用service服务的方法。
方法一:直接调用最简单的调用service服务的方法是直接调用其提供的方法。
首先,我们需要在文件中声明service组件,然后通过()方法来启动服务。
接下来,我们可以通过获取service实例来直接调用其方法。
// 启动serviceIntent intent = new Intent(context, );(intent);// 获取service实例并调用其方法MyService service = new MyService();();方法二:使用Intent启动Service除了直接调用service,我们还可以通过使用Intent来启动service。
这种方法更加灵活,可以方便地传递数据给service。
// 启动service并传递数据Intent intent = new Intent(context, );("key", value);(intent);在service的onStartCommand()方法中,我们可以通过Intent 获取传递的数据。
@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {if(intent != null) {String value = ("key");// 处理传递的数据}// 其他逻辑...}方法三:使用Messenger进行进程间通信有时候我们需要在不同的进程间进行通信,可以使用Messenger 实现。
android 的Activity和Service之间的通信在android中Activity负责前台界面展示,service负责后台的需要长期运行的任务。
Activity和Service之间的通信主要由IBinder负责。
在需要和Service 通信的Activity中实现ServiceConnection接口,并且实现其中的onServiceConnected和onServiceDisconnected方法。
然后在这个Activity中还要通过如下代码绑定服务:Java代码1.Intent intent = new Intent().setClass( this , IHRService.class);2.bindService( intent , this , Context.BIND_AUTO_CREATE );当调用bindService方法后就会回调Activity的onServiceConnected,在这个方法中会向Activity中传递一个IBinder的实例,Acitity需要保存这个实例。
代码如下:Java代码1.public void onServiceConnected( ComponentName inName , IBinderserviceBinder) {2. if ( inName.getShortClassName().endsWith( "IHRService" ) ){3. try {4. this.serviceBinder= serviceBinder;5. mService = ( (IHRService.MyBinder) serviceBinder).getService();6. //mTracker = mService.mConfiguration.mTracker;7. } catch (Exception e) {}8.9. }10.}在Service中需要创建一个实现IBinder的内部类(这个内部类不一定在Service中实现,但必须在Service中创建它)。
Service知识点整理Service简单概述Service(服务)是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件。
服务可由其他应用组件启动(如Activity),服务一旦被启动将在后台一直运行,即使启动服务的组件(Activity)已销毁也不受影响。
此外,组件可以绑定到服务,以与之进行交互,甚至是执行进程间通信(IPC)。
例如,服务可以处理网络事物、播放音乐、执行文件I/O或与内容提供程序交互,而这一切均可在后台进行。
Service基本上分为两种形式:启动当应用组件(如Activity)通过调用startService()启动服务时,服务即处于“启动”状态。
一旦启动,服务即可在后台无限期运行,即使启动服务的组件已被销毁也不受影响。
已启动的服务通常是执行单一操作,而且不会将结果返回给调用方。
例如,它可能通过网络下载或上传文件。
操作完成后,服务会自动停止运行。
绑定当应用组件通过调用bindService()绑定到服务时,服务即处于“绑定”状态。
绑定的服务提供了一个客户端-服务器接口,允许组件与服务进行交互、发送请求、获取结果,甚至是利用线程间通信(IPC)跨进程执行这些操作。
仅当与另一个应用组件绑定时,绑定服务才会运行。
多个组件也可以同时绑定到该服务,单全部取消绑定后,该服务即会被销毁。
无论应用处于启动状态还是绑定状态,抑或处于启动并且绑定状态,任何应用组件均可像使用Activity那样通过调用Intent来使用服务(即使此服务来自另外一个应用)。
不过,可以通过清单文件将服务声明为私有服务,并阻止其他应用访问。
基础知识通过创建Service子类(或使用它的一个现有子类)来创建服务。
在现实中,需要重写一些回调方法,已处理服务生命周期的某些关键方面并提供一种机制将组件绑定到服务。
onStartCommand()当另一个组件(如Activity)通过调用startService()请求启动服务时,系统将调用此方法。
android startforegroundservice详解Android StartForegroundService详解在Android开发中,我们经常需要在后台进行一些长时间运行的任务,如音乐播放器、下载管理器等。
在较新的Android版本中,为了提高系统性能并避免应用被系统杀死,Google引入了startForegroundService方法来启动在前台运行的服务。
本文将以"android startForegroundService详解"为主题,一步一步回答该主题。
第一步:什么是startForegroundService方法?startForegroundService方法是一个用于在Android系统中启动前台服务的方法。
在较新的Android版本中,如果我们使用startService方法启动一个服务,而该服务需要在后台执行长时间运行的任务,系统会认为该应用在后台运行过程中影响到了系统的正常性能,从而可能会将该应用杀死。
为了避免这种情况发生,我们可以使用startForegroundService 方法来启动一个前台服务,使得系统将该服务视为是用户正在进行互动的重要任务,提高其在系统中的优先级,从而减少被系统杀死的可能性。
第二步:使用startForegroundService的步骤是什么?使用startForegroundService方法启动前台服务的步骤如下:1. 在AndroidManifest.xml文件中为服务设置一个唯一的action。
xml<serviceandroid:name=".MyForegroundService"android:enabled="true"android:exported="true"><intent-filter><actionandroid:name="com.example.ACTION_FOREGROUND_SERVICE" /></intent-filter></service>2. 创建一个继承自Service的前台服务类。
Service概念及用途Android中的Service,其意思是“服务”,它是在后台运行,不可交互的。
Service自己不能运行,需要通过某一个Activity或者其它Context对象来调用,如Context .startService() 和Context.bindService()两种方式启动Service 。
Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们退出应用时,Service进程并没有结束,它仍然在后台运行,那我们什么时候会用到Service呢?比如我们播放音乐的时候,有可能想边听音乐边干些其他事情,当我们退出播放音乐的应用,如果不用Service,我们就听不到歌了,所以这时候就得用到Service了,又比如当我们一个应用的数据是通过网络获取的,不同时间(一段时间)的数据是不同的这时候我们可以用Service在后台定时更新,而不用每打开应用的时候在去获取。
如果在Service的onCreate或者onStart方法中做一些很耗时的动作,最好是启动一个新线程来运行这个Service,因为,如果Service运行在主线程中,会影响到程序的UI操作或者阻塞主线程中的其它事情。
Service生命周期Service的生命周期方法比Activity要少一些,只有onCreate、onStart、onDestroy。
有两种方式启动一个Service,他们对Service生命周期的影响是不一样的。
1)通过startService启动Service启动的时候会经历生成开始(onCreate onStart)过程,Service停止的时候直接进入销毁过程(onDestroy)。
而如果是调用者直接退出而没有调用stopService,Service会一直在后台运行。
直到下次调用者再启动起来,并明确调用stopService。
2)通过bindService启动通过bindService方法启动Service,其只会运行onCreate方法,如果调用退出了,Service会调用onUnbind,onDestroyed方法。
在Android开发中,Service是一种用于在后台执行长时间运行操作的组件,而不提供用户界面的应用程序组件。
以下是使用Android Service的一些基本用法:1.定义Service类:创建一个继承自Service的类,并重写其中的一些方法来执行所需的操作。
例如,可以在Service中执行网络请求、文件读写等操作。
2.注册Service:在AndroidManifest.xml文件中注册Service,以便系统可以找到并启动它。
例如:php复制代码<service android:name=".MyService" />3.启动Service:在Activity或其他组件中,使用Context的startService()方法来启动Service。
例如:java复制代码Intent intent = new Intent(this, MyService.class);startService(intent);4.绑定Service:如果需要在Service和Activity之间进行通信,可以使用bindService()方法来绑定Service。
通过回调接口,可以在Service和Activity之间传递数据或执行操作。
5.处理生命周期:由于Service在后台运行,不受Activity的生命周期限制,因此需要处理其自身的生命周期。
在Service中重写onStartCommand()或onBind()方法来执行所需的操作,并在不再需要时调用stopSelf()方法来停止Service。
6.通知用户:如果需要在Service执行某些操作时通知用户,可以使用NotificationManager来发送通知。
例如,可以在Service中发送一个通知,告知用户数据已成功下载或上传。
需要注意的是,使用Service需要谨慎处理资源的释放和生命周期的管理,以避免内存泄漏和资源浪费。
public class mService extends Service {//保存在service中的Activity对象private static mActivity m;//启动服务static void startservice(Context c){m=(mActivity)c;Intent iService=new Intent(c,mService.class);iService.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);c.startService(iService);}//关闭服务static void stopservice(Context c){Intent iService=new Intent(c,mService.class);iService.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);c.stopService(iService);}……//在mService中关闭mActivitym.finish();}public class mActivity extends Activity {// private MediaPlayer mMPlayer;/** (non-Javadoc)* @see android.app.Activity#onCreate(android.os.Bundle) */@Overrideprotected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stubsuper.onCreate(savedInstanceState);……//启动mServicemService.startservice(mActivity.this);……//停止mServicemService.stopservice(mActivity.this);}}主要包括3部分1. 定义application类,这个类可以保存获取activity实例,记得manifest中加入android:name=".MyApp"public class MyApp extends Application{private MyServiceActivity myActivity;public void setInstance(MyServiceActivity instance){myActivity = instance;}public MyServiceActivity getInstance(){return myActivity;}}2. 在activity中保存实例public class MyServiceActivity extends Activity {/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);((MyApp)getApplication()).setInstance(this);……}}3. 在service中取回实例public class MyService extends Service {MyServiceActivity myActivity;@Overridepublic void onCreate() {super.onCreate();setForeground(true);android.os.Debug.waitForDebugger();myActivity = ((MyApp)getApplication()).getInstance();……}}我试过第一个方法,可行的。
Android开发8.0版本启动Service的⽅法前⾔google在更新Android8.0后对Service的权限越发收紧。
导致⽬前想要启动服务必需实现服务的前台化(否则在服务启动5秒后,系统将⾃动报错)。
下⾯我们就来看看如何在8.0上启动服务。
看看8.0之前的版本怎么启动Service 在看8.0启动服务的⽅法之前,我们先看看8.0之前是怎么启动服务的。
这样可以对⽐,也可以理解增加了那些部分。
1.在Activity启动服务:Intent intent = new Intent(MainActivity.this,MainService.class);startService(intent); 8.0之前是使⽤startService 直接启动服务的。
后续服务就可以在后台运⾏了 2.将服务前台化: 虽然8.0之前如果没有明确需求,是可以不需要让服务前台化通知栏显⽰的,但是我们为了对⽐实现下8.0之前的服务前台化。
public void onCreate() {super.onCreate();Notification notification = new Notification.Builder(this).setContentTitle("主服务")//设置标题.setContentText("运⾏中...")//设置内容.setWhen(System.currentTimeMillis())//设置创建时间.setSmallIcon(R.mipmap.ic_launcher)//设置状态栏图标.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))//设置通知栏图标.build();startForeground(1,notification);}可以服务启动后,可以在服务的onCreate()⾥直接实现服务前台化。