Android本地服务.docx
《Android本地服务.docx》由会员分享,可在线阅读,更多相关《Android本地服务.docx(10页珍藏版)》请在冰豆网上搜索。
Android本地服务
Android支持服务的概念。
服务是在后台运行组件,没有用户界面。
可以将这些组件想象为Windows服务或UNIX服务。
与这些服务类型类似,Android服务始终可用,但无需主动执行某些操作。
Android支持两种服务类型的服务:
本地服务和远程服务。
本地服务无法供在设备上运行其他应用程序访问。
一般而言,这些服务类型仅支持承载该服务的应用程序。
而对于远程服务,除了可以承载服务的应用程序访问,还可以从其他应用程序访问。
远程服务使用AIDL(AndroidInterfaceDefinitionLanguage,Android接口定义语言)向客户端定义其自身。
Android中的服务
通过查看android.app.Service的公共方法,我们可以更深入地理解服务的概念。
ApplicationgetApplication();
AbstractIBinderonBind(Intentintent);
voidonConfigurationChanged(ConfigurationnewConfig);
voidonCreate();
voidonDestroy();
voidonLowMemory();
voidonRebind(Intentintent);
voidonStart(Intentintent,intstartId);
booleanonUnbind(Intentintent);
finalvoidsetForeground(BooleanisForeground);
finalvoidstopSelf();
finalvoidstopSelf(intstartId);
finalbooleanstopSelfResult(intstartId);
getApplication()方法返回实现服务的应用程序。
onBind()方法为在同一设备上运行的外部应用程序提供一个接口来与服务通信,此方法在远程服务中特别重要。
onConfigurationChanged();支持服务在设备配置更改时重新配置自身。
系统在首次创建服务时调用onCreate(),然后才调用onStart()。
此过程类似创建一个Activity的过程,在启动时执行一次初始化。
例如,如果创建后台线程,可以在onCreate()方法中进行,在确保在onDestroy()中停止该线程。
系统调用onCreate(),然后调用onStart(),最后在关闭服务时调用onDestroy()。
onDestroy()方法为服务提供了一种机制,在关闭之前执行最后的清理。
请注意,onStart()、onCreate()、和onDestroy()都是由系统调用的,不应该直接调用它们。
而且,如果在服务类中重写任何on*()方法,请确保从这些方法调用了超类的方法版本。
stopSelf()的各种版本为应用程序提供了一种机制来停止服务。
客户端也可以调用Context.stopService()来停止服务。
Android支持服务的概念有2个原因。
第一,简化后台任务的实施,这种服务也就是本地服务;第二,在同一设备上运行的应用程序之间执行进程通信,这种服务也就是远程服务。
本地服务与远程服务的一些重要区别。
具体来讲,如果服务完全只供同一进程中的组件使用(以运行后台任务),那么客户端必须调用Context.startService()来启动该服务。
这种类型的服务为本地服务,因为它的一般用途是运行承载服务的应用程序的后台任务。
如果服务支持onBind()方法,那么它属于远程服务,可通过进程间通信(Context.bindService())进程调用。
我们也将远程服务称为AIDL支持服务,因为客户端使用AIDL与服务通信。
尽管android.app.Service接口同时支持本地服务和远程服务,但并不建议提供一种服务的实现同时支持两种类型。
因为每种服务的类型都有预定义的生命周期,将两种服务合并在一起可能导致错误(尽管允许这么做)。
说明:
Android中的第二种服务类型有多种叫法:
远程服务、AIDL服务、外部服务和RPC服务。
这些名称都是指向同一类型的服务----------可供在设备上运行的其他应用程序远程访问的服务。
本地服务
本地服务由Context.startService()启动。
启动以后,这些类型的服务将持续运行,直到客户端调用服务的Context.stopService()或者服务自己调用stopSelf()。
请注意,当调用Context.startService()时,系统将实例化服务并调用服务的onStart()方法。
请记住,如果在服务启动之后(也就是服务运行时)调用Context.startService()不会为服务创建另一个实例,但这样做将调用服务的onStart()方法。
下面给出了两个本地服务的实例。
一:
定期在网络(比如Intent)上检索数据的服务(用于上传或下载信息)。
二:
任务执行程序服务,让应用程序的活动提交作业并对它们进行排队以供处理。
下面这个例子是一一个本地服务的例子这里例子是我们在服务的不同状态,如服务创建、服务启动、服务停止等定义一个消息通过状态栏来提醒用户后台服务的不同状态。
运行效果如下
先来看看我们的Service类
BackgroundService.java
Java代码
1packagexiaohang.zhimeng;
2
3importandroid.app.Notification;
4importandroid.app.NotificationManager;
5importandroid.app.PendingIntent;
6importandroid.app.Service;
7importandroid.content.Intent;
8importandroid.os.IBinder;
9
10publicclassBackgroundServiceextendsService{
11
12privateNotificationManagernotificationMgr;
13
14@Override
15publicvoidonCreate(){
16super.onCreate();
17notificationMgr=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
18
19displayNotificationMessage("startingBackgroundService");
20
21Threadthr=newThread(null,newServiceWorker(),"BackgroundSercie");
22thr.start();
23}
24
25@Override
26publicIBinderonBind(Intentintent){
27returnnull;
28}
29
30classServiceWorkerimplementsRunnable{
31@Override
32publicvoidrun(){
33//dobackgroundprocessinghere.....
34//stoptheservicewhendone...
35//BackgroundService.this.stopSelf()
36}
37}
38
39@Override
40publicvoidonDestroy(){
41displayNotificationMessage("stoppingBackgroundService");
42super.onDestroy();
43}
44
45@Override
46publicvoidonStart(Intentintent,intstartId){
47super.onStart(intent,startId);
48}
49
50privatevoiddisplayNotificationMessage(Stringmessage){
51Notificationnotification=newNotification(R.drawable.icon,message,
52System.currentTimeMillis());
53
54PendingIntentcontentIntent=PendingIntent.getActivity(this,0,
55newIntent(this,Activity01.class),0);
56
57notification.setLatestEventInfo(this,"BackgroundService",message,
58contentIntent);
59
60notificationMgr.notify(R.id.app_notification_id,notification);
61}
62}
Activity01类
Java代码
63packagexiaohang.zhimeng;
64importandroid.app.Activity;
65importandroid.content.Intent;
66importandroid.os.Bundle;
67importandroid.util.Log;
68importandroid.view.View;
69importandroid.view.View.OnClickListener;
70importandroid.widget.Button;
71
72publicclassActivity01extendsActivity{
73
74privatestaticfinalStringTAG="Activity01";
75
76@Override
77publicvoidonCreate(BundlesavedInstanceState){
78super.onCreate(savedInstanceState);
79setContentView(R.layout.main);
80
81Log.d(TAG,"startingservice");
82
83ButtonbindBtn=(Button)findViewById(R.id.bindBtn);
84bindBtn.setOnClickListener(newOnClickListener(){
85@Override
86publicvoidonClick(Viewv){
87startService(newIntent(Activity01.this,
88BackgroundService.class));
89}
90});
91
92ButtonunbindBtn=(Button)findViewById(R.id.unbindBtn);
93unbindBtn.setOnClickListener(newOnClickListener(){
94@Override
95publicvoidonClick(Viewv){
96stopService(newIntent(Activity01.this,BackgroundService.class));
97}
98});
99}
100}
布局文件
Xml代码
101
xmlversion="1.0"encoding="utf-8"?
>
102android="
103android:
orientation="vertical"
104android:
layout_width="fill_parent"
105android:
layout_height="fill_parent"
106>
107108android:
layout_width="fill_parent"
109android:
layout_height="wrap_content"
110android:
text="@string/hello"
111/>
112id="@+id/bindBtn"
113android:
layout_width="wrap_content"
114android:
layout_height="wrap_content"
115android:
text="Bind"/>
116id="@+id/unbindBtn"
117android:
layout_width="wrap_content"
118android:
layout_height="wrap_content"
119android:
text="UnBind"/>
120
我们需要创建一个图标并将其放在项目的drawable文件夹内,我用的项目自带的那个。
需要为通知管理器NotificationManager提供一个应用程序级唯一ID(整数)。
要创建唯一ID,可以向字符串资源文件/res/values/strings.xml添加一个项ID。
当调用notify()方法时,会将唯一ID传递给通知管理器。
Xml代码
121
最后,需要向AndroidManifest.xml文件添加
Xml代码
122name=”BackgroundService”/>
标记,将其作为的子标签。
BackgroundServie是承载服务的应用程序组件使用服务的一个典型例子。
换言之,运行服务的应用程序也是服务的唯一使用者。
因为该服务不支持其进程外的客户端,所以它是本地服务。
由于本地服务不是远程服务,所以它在bind()方法中返回null。
因此,绑定此服务的唯一方法是调用Context.startService()。
本地服务的重要方法包括onCreate()、onStart()、stop()*和onDestroy()。
在BackgroundService的onCreate()方法中,我们创建了一个线程来完成服务的主要工作。
我们需要应用程序的主线程来处理用户界面,所以将服务的工作委派给一个辅助线程。
另请注意,我们在onCreate()而不是onStart()中创建和启动线程。
这样做是因为,onCreate()只会被调用一次,我们也希望在服务生命周期内只创建一次该线程。
onStart()方法可以调用多次,所以它不符合此处的要求。
我们在线程的run()方法实现中没有做任何事情,可以在这里执行HTTP调用、查询数据库等。
BackgroundService还使用NotificationManager类,以在服务启动和停止时向用户发送通知。
这是本地服务将信息传递回用户的一种方式。
要向用户发送通知,需要调用getSystemService(NOTIFICATION_SERVICE)来获得通知管理器。
来自通知管理器的消息将显示在状态栏中。