四大组件
Activity
ContentProvider
BroadcastReceiver
Service
Service
一,
Service 是四大组件之一, 和Activity非常相似, 一般运行在后台, 没有用户界面, 是一个可执行的程序
二,
Service和Activity的区别
不同点:
Activity: 可以和用户交互, 页面可见
Service : 后台运行, 没有界面
相同点:
注册方式都是清单文件中注册, 他们都有自己的生命周期
三, Service和Activity的选择标准
当系统获取数据时, 需要和用户交互, 并且展示给用户, 则使用Activity
当系统获取数据时, 过程不展示给用户, 只需要将数据结果返回, 则使用Service
四, Service的主要用途
1, 播放音频
2, 用于记录当前的地理位置
3, 下载大文件
五, API文档中, Service不是什么:
1, Service 不是一个单独的进程, 除非另有规定, 否则它和应用程序运行在同一个进程中
2, Service 也不是一个单独的线程, 默认情况下, 运行在主线程中
六,
服务的分类
1, 本地服务
在应用程序内部
启动方式:
1, Context.startService()
2, Context.bindService()
2, 远程服务 AIDL, 信使
android系统内的应用程序之间, 进行数据的传递
七, 创建方式
1, 定义一个类, 继承Service
2, 重新父类的方法onBind(Intent intent)
3, 在清单文件中注册 <service android:name="全类名"/>
八, 启动服务的生命周期
Context.startService() 启动服务
Context.stopService() 停止服务
执行的方法:
onCreate() -- onStartCommand() -- onDestroy()
当Servier被创建时执行onCreate(), 当服务被启动时执行onStartCommand()
多次启动一个已有服务,不会执行onCreate(), 每次都会执行onStartCommand()
当服务被停止时, 执行onDestroy()
特点:
1, 启动源和服务没有关系
2, 无法得到启动源中的服务对象
注意:
如果启动源和服务之间进行数据的传递, 就不能使用startService() ,
而必须要使用bindService() 来绑定服务, unbindService() 来解除绑定
八, 绑定服务的生命周期
bindService() 绑定服务
unbindService() 解除绑定
onCreate() --- onBind() -- onUnbind() -- onDestroy()
同一个服务, 只能被同一个启动源绑定一次, 除非解绑后, 可以再次绑定
十, 先通过startService()启动服务, 再通过bindService() 绑定服务 执行的生命周期
onCreate() -- onStratCommand() -- onBind() -- onUnbind() -- onDestroy()
创建服务只会被执行一次, 直到销毁
服务的调用者
都结束
, 在服务才会执行onDestroy()
注意:
如果startService启动的服务, 当前Activity被finish掉, 服务不会停止
如果bindService绑定的服务, 当前的Activity被finish掉, 绑定的服务也会被销毁
十一, 服务分类
1, 按是否跨App
本地服务
远程服务
2, 按触发方式
启动型服务
绑定型服务
3, 按服务是否能恢复 startService --- startCommand 方法的返回值
粘性服务 一旦服务被异常终止, 是可以恢复继续执行
非粘性服务 一旦服务被异常终止, 则不会恢复
START_STICKY 粘性服务 1
启动的服务和应用程序是"粘"在一起, 执行onStartCommand() ,
如果服务被kill后, 系统会自动重启服务
当启动服务时, 传入的第一个参数将为null
START_NOT_STICKY 非粘性服务 2
执行onStartCommand(),如果服务被kill后,系统不会自动重启服务
START_REDELIVER_INTENT 重传Intent 3
执行onStartCommand(),如果服务被kill后,系统会自动重启该服务, 并且将Intent值传入
十二, 跨进程间的通信 -- 远程服务
1, 信使 Messenger
在server端和client端中, 数据通过Messenger对象来传递消息,
这个对象相当于一个信息的中转站, 所有的信息都需要通过这个对象来携带
客户端如果要向服务端发送信息, 则需要先的到服务端的信使对象
步骤:
Servier端
1, 创建一个信使对象
Messenger messenger = new Messenger(handler);
2, 创建信息的处理器对象Handler, 处理客户端返回的信息(Message)
3, 在onBind() 方法中, 返回IBinder对象, messenger.getBinder();
4, 在清单文件中注册, 提供一个过滤器, 指定action, 可以获取其他APP发送的数据
Client端
1, 绑定服务
Intent intent = new Intent("
action动作,需要和服务器提供的一致
");
//5.0 需要添加设置包名
intent.setPackage("服务器端的packageName");
bindService......
2, 如果绑定成功后, 在ServiceConnection中的ServiceConnected() 方法中, 得到服务器的信使对象
serverMessenger = new Messenger(Ibinder);
3, 通过信使对象, 发送消息
Message message = Message.obtain();
message.arg1 = 99;
serverMessenger.send(message);
4, 如果客户端要接收服务器返回的数据, 那些就需要在发送消息的同时, 提供返回的clientMessenger
Messenger clientMessenger = new Messenger(handler);
message.replyTo = clientMessenger;
2, AIDL Android Interface Definition Language 安卓接口定义语言
实现了跨进程间的通信
实现步骤:
服务端:
1, 在src/main 中创建AIDL文件, 接口, 定义业务的方法, 这些方法的话不能加修饰符
2, 编译下, 自动生成一个文件 build/generated/source/aidl/debug/ DataService.java
3, 在服务器端需要定义Service, 重写父类的方法onBind(), 在该法中返回Ibinder
客户端:
1, 把服务器中的src/main的AIDL复制到客户端的同等目录下
2, 编译下, 自动生成一个文件 build/generated/source/aidl/debug/ DataService.java
3, 绑定服务, 服务绑定成功后, 在onServiceConnected() 方法中, 可以的到DateService
DataService dataService = DataService.Stub.asInterface(Ibinder);
4, 可以通过DataService 接口, 调用接口中对应的方法, 得到需要的数据
原理:
在Android中自带了一块可以存放AIDL文件的区域, 服务器可以通过AIDL 写入需要传递给客户端的内容
然后通过onBind()方法 , 返回一个Binder对象(继承于Binder类, 是实现了 AIDL接口的Stub对象)
在客户端中也需要一个AIDL文件, 这样才能取到服务器端在共享区域中保存的数据和内容, 客户端必须通过bindService得到接口对象