Android 组件Service
Service具有以下特点:
可以没有用户界面,不需要与用户交互。
可以长期运行,并且不占程序控制权(焦点)
比Activity 的优先级高,不会轻易被Android系统终止,即使Service被系统终止,在系统资源恢复后Service也将自动恢复成运行状态。
用于进程间通信(Inter Process Communication, IPC),解决两个不同Android应用程序进程之间的调用和通讯问题
Service运行方式
- 本地服务 Local Service 用于应用程序内部:
在这种方式下,它以调用Context.startService()启动,而以调用Context.stopService()结束。不论调用了多少次startService()方法,只需要调用一次stopService()来停止。 - 远程服务 Remote Service 用于android系统内部的应用程序之间:
可以通过自己定义并暴露出来的接口进行程序操作。客户端建立一个到服务对象的连接,并通过那个连接来调用服务。连接以调用Context.bindService()方法建立,以调用 Context.unbindService()关闭。多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载它。
Service操作
Service生命周期
- 启动方式的Service生命周期
开始于Context.startService()
结束于Context.stopService() - 绑定方式的Service生命周期
开始于Context.bindService()
结束于Context.unbindservice
解析Service的实现
(创建和配置Service)
1.创建:定义一个继承Service的子类;
并且覆盖Service类提供的OnBind、onCreate、onStartCommand以及onDestroy等方法。
OnBind方法是Service子类必须实现的方法。
onCreate方法在Service第一次被创建后将立即回调该方法。
onStartCommand方法在每次调用startService(Intent)方法启动该Service时回调该方法。
onDestroy方法在Service终止时调用。
2.配置:在AndroidManifest.xml文件中使用< service android:name=".ExampleService"/>
标签配置该Service。(与Activity同级)
启动Service
启动方式是最常用的启动Service的方式,这种方式通过调用Context.startService(intent)来启动Service。此方法访问者与Service之间没有关联,即使访问者退出也不影响Service运行。
捆绑方式先使用通过Context.bindService()来建立同指定Service的服务链接(Connection),然后通过这个服务链接来启动Service的对象。此方法访问者与Service绑定在一起,访问者一旦退出,Service随即终止。
bind和start启动方式的不同
通过 bindService() 方法启动时和 startService() 方法一样,都会调用 onCreate() 方法来创建 Service,但它不会调用 onStartCommand() 方法,而是调用 onBind() 方法返回客户端一个 IBinder 接口。这个 IBinder 就是在 Service 的生命周期回调方法 onBind() 中的返回值。
绑定一个已经存在的Service
通过bindService方法实现,这个方法的原型是: bindService(Intent inent ,ServiceConnection serviceConnection,int flags)
第一个参数是一个Intent对象,这个对象指定了需要绑定的Service
第二参数(serviceConnection)用于监测Service与访问者之间的连接情况
第三个参数指定被绑定的service的创建方式,例如当这个参数为Context.BIND_AUTO_CREATE时,则在绑定时自动创建service
绑定Service的步骤
建立ServiceConnection对象,并且重写ServiceConnection的onServiceConnected方法和onServiceDisconnected方法
创建被绑定的Service的Intent对象
将步骤1和步骤2创建的对象作为形参传递给bindService方法,执行bindService方法来绑定Service。若绑定Service成功,则onServiceConnected的方法会被执行;否则onServiceDisconnected会被执行。
远程Service调用
远程Service调用就是应用程序之间的Service调用,需要使用Android提供AIDL(Android Interface Definition Language)来实现。AIDL是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(IPC)的代码。AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。
使用AIDL实现Service的远程调用的步骤
- 创建后缀名为aidl的AIDL文件
package com.example.ex6_4remoteservice;
interface IStudent{
void setStudentID(int StudentID);
int getStudentID();
}
保存后,会在gen目录下生成同名的java接口代码。
- 实现AIDL文件生成的JAVA接口
编译器会根据AIDL接口产生一个Java接口,并且实现一些必要的附加方法供远程调用,这个接口有一个名为Stub的内部抽象类,必须创建一个类来扩展这个Stub内部抽象类
public class MyServiceImpl extends IStudent.Stub {
int StudentID;
public void setStudentID(int StudentID) throws RemoteException {
this.StudentID=StudentID;
}
public int getStudentID() throws RemoteException {
return StudentID;
}
}
- 向客户端暴露接口
一般通过定义一个Service来实现,在Service的onBind()方法中返回该接口,当我们绑定该服务时调用该方法。
public class MyService extends Service{
private Stub StudentInfo=new MyServiceImpl();
public IBinder onBind(Intent intent) {
return StudentInfo;}}
- 在客户端调用
定义一个Activity来绑定远程Service,通过IStudent.Stub.asInterface(service)获得IStudent接口实例 - AndroidManifest.xml文件中添加服务声明
定义一个Activity来绑定远程Service,通过IStudent.Stub.asInterface(service)获得IStudent接口实例
< service android:name="MyService">
</ service>
系统Service
- 电话管理器TelephoneManager
获得系统服务 tManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
电话状态监听
PhoneStateListener listener = new PhoneStateListener()
添加事件监听
tManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
清单文件添加访问权限
< uses-permission android:name=“android.permission.READ_PHONE_STATE”/> - 短信管理器SmsManager