530 likes | 684 Views
第 6 章 Android Service 组件. 本章导学. 6.1Service 组件简介 6.2 启动和停止 Service 6.3 绑定本地 Service 并与之通信 6.4Service 的生命周期 6.5 跨进程调用 Service(AIDL 服务) 6.6 系统服务. 6.1Service 组件简介. Serice 是四喜丸子之一,地位和 Activity 并列。是运行在后台的一种服务程序,一般很少和用户交互,没有可视化界面。. 6.1Service 组件简介. Serice 本质 (TCP Socket). 6.1Service 组件简介.
E N D
本章导学 • 6.1Service组件简介 • 6.2启动和停止Service • 6.3绑定本地Service并与之通信 • 6.4Service的生命周期 • 6.5跨进程调用Service(AIDL服务) • 6.6系统服务
6.1Service组件简介 • Serice是四喜丸子之一,地位和Activity并列。是运行在后台的一种服务程序,一般很少和用户交互,没有可视化界面。
6.1Service组件简介 • Serice本质(TCP Socket)
6.1Service组件简介 • 创建Service: • 步骤1:写个类继承Service类 • 步骤2:配置。在AndroidManifest.xml中声明。 • Service的调用方式: • startService(intent) • bindService(intent) • 通过RPC(远程进程调用)机制来实现不同进程间Service的调用。
6.1Service组件简介 • Service的分类 • 本地服务—用于应用程序内部 • 远程服务---用于应用程序之间
本章导学 • 6.1Service组件简介 • 6.2启动和停止Service • 6.3绑定本地Service并与之通信 • 6.4Service的生命周期 • 6.5跨进程调用Service(AIDL服务) • 6.6系统服务
6.2启动和停止Service • 启动服务用于Activity和Service之间不需要交互的情形 • Intent intent = new Intent(); • intent.setAction(…); • startService(intent); //启动服务 • stopService(intent); //停止服务
6.2启动和停止Service • 项目实例演示: • FirstService • 课堂编程实现
6.2启动和停止Service • Service是什么? 1、Service 是一个运用程序组件; 2、Service 没有图形化界面; 3、Service通常来处理一些耗时较长的操作; 4、可以使用Service更新Content Provider,发送Intent以及启动系统的通知等等。 • Service不是什么? 1、Service不是一个单独的进程; 2、Service不是一个线程。
本章导学 • 6.1Service组件简介 • 6.2启动和停止Service • 6.3绑定本地Service并与之通信 • 6.4Service的生命周期 • 6.5跨进程调用Service(AIDL服务) • 6.6系统服务
6.3绑定本地Service • 某Activity通过startService()和stopService()启动、关闭service时,Service与该Activity之间基本上不存在太多关联,因此该Service与访问它的activity之间无法进行通信、数据交换。
6.3绑定本地Service • 数据交换:通过bindService()和unbindService()方法启动、关闭服务。(数据库连接) • 绑定Service需要三个参数:bindService(intent service , ServiceConnection conn , int flag); • 第一个是sevice:该参数通过Intent指定要启动的service; • conn:该参数是一个ServiceConnection对象,该对象用于监听访问者与Service之间的连接情况。当访问者与Service之间连接成功时将回调ServiceConnection对象的方法onServiceConnected(ComponentName name, IBinder service);当访问者与Service之间断开时将回调 ServiceConnection对象的方法onServiceDisconnected(ComponentName name)。 • flag:指定绑定时是否自动创建service。
6.3绑定本地Service • ServiceConnection对象里onServiceConnected方法中有一个Ibinder对象,该对象即可实现与被绑定Service之间的通信。 • 开发service时,该service必须提供一个IBinder onBind(Intent intent)方法,在绑定本地service的情况下,Onbind返回的IBinder对象将会传给ServiceConnection对象里onServiceConnected(ComponentName name, IBinder service)方法中的sevice参数。 • Service与该服务的调用者之间通过Binder通信。
6.3绑定本地Service • 项目实例演示: • BindService MainActivity.bindService()->BindService.onCreate()->BindService.onBind()->MainActivity.ServiceConnection.onServiceConnection()->BindService.MyBinder.getCount()。
6.3绑定本地Service • Linux进程通信方式(IPC) • 共享内存 • 信号量 • 管道 • 消息队列 • socket
6.3绑定本地Service • Binder介绍
6.3绑定本地Service • Android手机中没有采用传统的IPC通信方式的原因 • 传输性能 • 各种IPC方式数据拷贝次数 • 安全性
6.3绑定本地Service • Binder 通信模型,四个角色 • Server(用户空间) • Client (用户空间) • ServiceManager (用户空间) • 驱动(内核空间)
本章导学 • 6.1Service组件简介 • 6.2启动和停止Service • 6.3绑定本地Service并与之通信 • 6.4Service的生命周期 • 6.5跨进程调用Service(AIDL服务) • 6.6系统服务
6.4Service生命周期 • Service生命周期主要包含以下几个方法: • onCreate() • onBind(Intent intent) • onStart(Intent intent,int startId) • onDestory() • 启动服务时,如果尚未创建,则先调用onCreate()方法,再调用onStart() • 绑定服务时,如果尚未创建,则先调用onCreate()方法,再调用onBind()
本章导学 • 6.1Service组件简介 • 6.2启动和停止Service • 6.3绑定本地Service并与之通信 • 6.4Service的生命周期 • 6.5跨进程调用Service(AIDL服务) • 6.6系统服务
6.5跨进程调用Service(AIDL服务) • 不同进程间对象方法的相互调用 • Window的DCOM • CORBA远程调用 • JAVA的RMI
6.5跨进程调用Service(AIDL服务) • AIDL服务: • 为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现。与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口。因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。
6.5跨进程调用Service(AIDL服务) • 组成 • 服务端 • 客户端
6.5.1服务端实现 • 步骤1:新建服务端工程,AidlService
6.5.1服务端实现 • 步骤2:定义aidl接口,将客户端需要访问的方法在aidl文件中定义 ICat.aidl interface ICat { String getColor(); double getWeight(); }
6.5.1服务端实现 • 步骤3:定义Service类,将aidl接口暴露给客户端 AidlService.java public class AidlService extends Service { Private String color; Private double weight; public class CatBinder extends Stub { public String getColor() throws RemoteException { return color; } public double getWeight() throws RemoteException{ return weight; } } 注意内部类CatBinder的命名
6.5.1服务端实现 • 步骤3:定义Service类,将aidl接口暴露给客户端 AidlService.java public class AidlService extends Service { Private String color; Private double weight; public class CatBinder extends Stub { } public IBinder onBind(Intent arg0){ return catBinder; } } 注意内部类CatBinder的命名,见完整代码
6.5.1服务端实现 • 步骤4:AndroidManifest.xml文件中配置Service <service android:name=".AidlService" > <intent-filter> <action android:name=“com.hnu.aidls.action.AIDL_SERVICE" /> </intent-filter> </service>
6.5.2客户端实现 • 步骤1:新建客户端工程,Aidlclient
6.5.2客户端实现 • 步骤2:将服务端中定义的ICat.aidl文件拷贝到客户端工程项目中
6.5.2客户端实现 • 步骤3:创建客户端类(activity),客户端类绑定远程Service • 创建ServiceConnection对象 • 以ServiceConnection对象作为参数,调用Context的 bindService()方法绑定远程Service
6.5.2客户端实现 • 步骤3:创建客户端类(activity),客户端类绑定远程Service private ServiceConnection conn = new ServiceConnection(){ public void onServiceConnected(ComponentName name, IBinder service){ // 获取远程Service的onBind方法返回的对象的代理 catService = ICat.Stub.asInterface(service); } public void onServiceDisconnected(ComponentName name){ catService = null; } }; 见完整代码
6.5.2客户端实现 • 跨进程调用Service与本地Service的区别: • 本地Service客户端得到是onBinder方法返回值 • 跨进程Service客户端得到是onBinder方法返回对象的代理
6.5.3传递复杂数据的AIDL服务 • 需求: • 服务端存储每个人养的宠物 • 客户端输入用户姓名,可以从服务端那里查询该用户养的宠物,并显示在界面上。
6.5.3传递复杂数据的AIDL服务 • 需求: • Person对象作为调用远程Service的参数 • Pet对象作为返回值
6.5.3传递复杂数据的AIDL服务 • RMI:要求远程调用的参数和返回值必须实现Serializable接口 • Android:参数和返回值必须实现Parcelable接口
6.5.3传递复杂数据的AIDL服务 • 步骤1,创建服务端工程:ComplexService
6.5.3传递复杂数据的AIDL服务 • 步骤2,定义3个aidl文件 • IPet.aidl • Person.aidl • Pet.aidl
6.5.3传递复杂数据的AIDL服务 • 步骤3,定义3个java文件 • Person.java • Pet.java • ComplexService.java
6.5.3传递复杂数据的AIDL服务 • 步骤4:AndroidManifest.xml文件中配置Service <service android:name=".ComplexService" > <intent-filter> <action android:name=“com.hnu.aidls2.action.COMPLEX_SERVICE" /> </intent-filter> </service>
6.5.3传递复杂数据的AIDL服务 • 步骤5,建立客户端工程ComplexClient
6.5.3传递复杂数据的AIDL服务 • 步骤6,将服务端工程中的3个aidl文件、Person.java、Pet.java拷贝到客户端工程中
6.5.3传递复杂数据的AIDL服务 • 步骤7,建立ComplexClient.java