startService方式与bindService方式开启服务时,服务生命周期中所执行的方法时不同的,如:
onCreate():第一次创建服务时执行的方法 onDestroy():服务被销毁时执行的方法
onStartCommand():客户端通过调用startService(Intent, Service)显示启动服务时执行该方法。
onBind():客户端通过调用bindService(Intent, Service, int)启动服务时执行该方法。
onUnbind():客户端调用unBindService(ServiceConnection conn)断开服务绑定时执行的方法。
这些方法都是Service生命周期中重要的回调方法,通过这些方法可以观察服务的创建、开启、绑定、解绑、销毁等过程。
4、服务的启动方式
使用startService()方式开启服务的具体代码如下所示: Intent intent = new Intent(this, StartService.class); Context.startService(intent); Context.stopService(intent);
服务也是Android中的四大组件之一,因此需要在清单文件中注册 当程序使用startService()和stopService()启动、关闭服务时,服务与调用者之间基本不存在太多的关联,也无法与访问者进行通信、数据交互等。如果服务需要与调用者进行方法调用和数据交互时,应该使用bindService()和unbindService()启动、关闭服务。 bindService(Intent service,ServiceConnection conn, int flags) Intent对象用于指定要启动的Service ServiceConnection对象用于监听调用者与Service的连接状态。 flags指定绑定时是否自动创建Service(如果Service还未创建)。 5、服务的通信 本地的通信 在Android系统中,服务的通信方式有两种,一种是本地服务通信,一种是远程服务通信。 本地服务通信是指应用程序内部的通信,而远程服务通信是指两个应用程序之间的通信。使用这两种方式进行通信时必须满足一个前提,就是服务必须以绑定方式开启。 在进行本地服务通信时,可以使用Service类提供的IBinder onBind(Intent intent)方法,该方法返回的IBinder对象会作为参数传递给ServiceConnection类中 onServiceConnected(ComponentName name,IBinder service)方法,这样访问者就可以通过IBinder对象与Service进行通信。 Service类 IBinder Onbind(Intent intent)方法ServiceConnection类onServiceConnected(ComponentName name, IBinder service)方法通过IBinder对象实现通信 远程通信 远程服务通信是通过AIDL(Android Interface Definition Language)实现的,它是一种接口定义语言(Interface Definition Language),其语法格式非常简单,与Java中定义接口很相似。 但还存在差异: 1、AIDL定义接口的源代码必须以.aidl结尾 2、AIDL接口中用到的数据类型,除基本类型,String,CharSequence,List,Map之外,其他类型全部需要导入包,即使他们在同一个包中。 定义AIDL接口,实质上只是定义了进程间通信接口,服务端、客户端都需要使用Android SDK目录下的platform-tools子目录下的aidl.exe工具为该接口提供实现。如果使用ADT工具进行开发,则ADT会自动实现AIDL接口。 远程服务通信是通过AIDL(Android Interface Definition Language)实现的,它是一种接口定义语言(Interface Definition Language),其语法格式非常简单,与Java中定义接口很相似。 package cn.itcast.service; interface IService{ String getName(); int getPrice(); } 定义好AIDL接口之后,接着需要在应用程序中创建Service的子类。该Service的onBind()方法所返回的IBinder对象应该是ADT所生成的IService.Stub的子类。 第八章 内容提供者 1、教学要求 了解什么是内容提供者。 学会使用内容提供者。 学会使用ContentResolver操作其他应用的数据。 学会使用内容观察者观察其他应用数据的变化。 2、内容提供者 Android中内容提供者的作用 为了实现这些功能,Android系统提供了一个跨应用进行数据访问的组件,这个组件就是内容提供者ContentProvider。 通过ContentResolver操作A应用数据B应用操作暴露的数据ContentResolver返回操作结果返回操作结果A应用使用ContentProvider暴露的数据 定义一个类继承android.content包下的ContentProvider类(抽象类)。子类需要重写它的onCreate()、delete()、getType()、insert()、query()、update()这几个抽象方法。 ContentProvider是四大组件之一,必须要在清单文件中注册 3、数据暴露的安全性问题 当使用provider暴露敏感数据时,为了数据安全,在注册ContentProvider时,还可以为其设定一些列的权限,具体操作如下: 利用android:permission属性,如果在注册provider时使用了该属性,则其他应用访问该ContentProvider时必须加上该权限,否则会报异常。如:PersonDBProvider注册了下述权限,android:permission=“mobile.permission.PROVIDER”,则其他应用访问该Provider时需要加上 此外,还可以为Provider配置android:readpermission属性,如果在注册了provider时使用了该属性,那么其他应用在使用query方法查询数据时,必须加上该权限。 android:writePermission属性,如果在注册provider时使用该属性,那么其他应用通过 ContentProvider的增、删、改这个几个方法操作数据时需要加上该权限。 如果在注册Provider时为其指定了自定义权限(即系统内不存在的权限)。为了让权限生效,首先需要单击清单文件中的permission标签页的Add按钮,进行添加。 4、Uri简介 ContentProvider的几个抽象方法,这几个抽象方法中有一个参数Uri,它代表了数据的操作方法。Uri是由scheme、authorites、path三部分组成。 content://cn.itcast.db.personprovider/person schemeauthoritiespath scheme:“content://”是一个标准的前缀,表明这个数据被内容提供者所 控制,它不会被修改; ? authorities:“cn.itcast.db.personprovider”是在清单文件中指定的 android:authorities属性值,该值必须唯一,它表示了当前的内容提供者; ? path:“/person”代表资源(或者数据),当访问者需要操作不同数据时,这 个部分是动态改变的。 Uri类常用方法 Uri.parse(String str)方法是将字符串转化成Uri对象的。为了解析Uri对象,Android系统提供了一个辅助工具类UriMatcher用于匹配Uri。 UriMatcher类中的常用方法如表所示: 方法名称 方法说明 创建UriMatcher对象时调用,参数通常使用UriMatcher.NO_MATCH,表示路径不满足条件返回-1 ? public UriMatcher(int code) public void addURI(String 添加一组匹配规则,authority即Uri的authoritites部分,authority, String path, int code) path即Uri的path部分 匹配Uri与addURI方法相对应,匹配成功则返回addURI方法中传入的参数code的值。 public int match(Uri uri) 5、内容提供者的访问 在Android系统中,ContentResolver充当着桥梁的角色。应用程序通过ContentProvider暴露自己的数据,通过ContentResolver对应用程序暴露的数据进行操作。 在使用ContentProvider暴露数据时提供了相应的Uri,因此,访问现有的ContentProvider时要指定相应的Uri,然后通过ContentResolver对象来实现数据的操作。 6、内容观察者 使用ContentProvider将数据共享出来后,再使用ContentResolver查询ContentProvider共享出来的数据。如果应用程序需要监听ContentProvider共享的数据是否发生变化,可以 使用ContentObserver(内容观察者)对数据进行监听。 当数据发生变化是向消息中心发送消息观察消息中心的消息,通过消息观察A应用数据变化消息中心C应用注册ContentObserverA应用使用ContentProvider暴露数据并调用ContentResolver的notifyChange()方法观察到变化的数据触发onChange()方法操作A应用中的数据B应用使用ContentResolver 内容观察者常用方法 方法名称 方法说明 ContentObserver(Handler ContentObserver的派生类都需要调用该构造方法。参数可以是handler) 主线程Handler(可以更新UI ),也可以是任何Handler对象。 public void onChange(boolean selfChange) 当观察到的Uri代表的数据发生变化时,会触发该方法。