Android ServiceConnection
绑定到一个Service
应用组件(客户端)可以调用bindService()绑定到一个service.Android系统之后调用service的onBind()方法,它返回一个用来与service交互的IBinder.
绑定是异步的.bindService()会立即返回,它不会返回IBinder给客户端.要接收IBinder,客户端必须创建一个ServiceConnection的实例并传给bindService().ServiceConnection包含一个回调方法,系统调用这个方法来传递要返回的IBinder.
注:只有activities,services,和contentproviders可以绑定到一个service—你不能从一个broadcastreceiver绑定到service.
所以,从你的客户端绑定到一个service,你必须:
1实现ServiceConnection.
你的实现必须重写两个回调方法:
onServiceConnected()
系统调用这个来传送在service的onBind()中返回的IBinder.
OnServiceDisconnected()
Android系统在同service的连接意外丢失时调用这个.比如当service崩溃了或被强杀了.当客户端解除绑定时,这个方法不会被调用.
2调用bindService(),传给它ServiceConnection的实现.
3当系统调用你的onServiceConnected()方法时,你就可以使用接口定义的方法们开始调用service了.
4要与service断开连接,调用unbindService().
当你的客户端被销毁,它将从service解除绑定,但是你必须总是在你完成与service的交互时或当你的activity暂停于是service在不被使用时可以关闭此两种情况下解除绑定.(下面会讨论更多在适当的时候绑定和解除绑定的问题.)
例如,下面是前一篇"派生Binder类"中创建的代码片段,它把客户端连接到了service.所有需要做的就是把返回的IBinder强制转换到LocalBinder类并且请求LocalService实例:
LocalService mService;
private ServiceConnection mConnection = new ServiceConnection() {
// 当与service的连接建立后被调用
public void onServiceConnected(ComponentName className, IBinder service) {
// Because we have bound to an explicit
// service that is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
} // 当与service的连接意外断开时被调用
public void onServiceDisconnected(ComponentName className) {
Log.e(TAG, "onServiceDisconnected");
mBound = false;
}
};
使用这个ServiceConnection,客户端可以绑定到一个service,通过把它传给bindService().例如:
Intentintent = new Intent(this, LocalService.class);
bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
第一个bindService()的参数是一个明确指定了要绑定的service的Intent.
第二个参数是ServiceConnection对象.
第三个参数是一个标志,它表明绑定中的操作.它一般应是BIND_AUTO_CREATE,这样就会在service不存在时创建一个.其它可选的值是BIND_DEBUG_UNBIND和BIND_NOT_FOREGROUND,不想指定时设为0即可.
补充事项
下面是一些关于绑定到service的重要事项:
你总是需要捕获DeadObjectException异常.它会在连接被打断时抛出.这是被远程方法抛出的唯一异常.
对象引用计数是跨进程的作用的.
你应该在客户端的生命期内使绑定和解除绑定配对进行,例如:
如果你需要在你的activity可见时与service交互,你应该在onStart()绑定并在onStop()中解除绑定.
如果你想让你的activity即使在它停止时也能接收回应,那么你可以在onCreate()中绑定并在onDestroy()中解除绑定.注意这意味着你的activity需要使用在自己整个运行期间使用service(即使位于后台),所以如果service在另一个进程中,那么你增加了这个进程的负担而使它变得更容易被系统杀掉.
注:你一般不应该在你的activity的onResume()和onPause()中绑定和解除绑定到service,因为这些回调方法,出现在每个生命期变化中,并且你需要使发生在这些变化中的处理最小化.还有,如果你应用中的多个activity绑定到同一个service,并且有一个变化发生在其中两个activity之间,service可能在当前activity解除绑定(pause中)和下一个绑定前(rusume中)被销毁又重建.
管理BoundService的生命期
当一个service的所有客户端都解除绑定,Android系统就销毁它(除非它是从onStartCommand()启动).如果你的service是一个纯boundservice,你不需管理它的生命期—Android系统会为你管理它.
然而,如果你选择了实现onStartCommand()回调方法,那么你必须明确地停止service,因为service现在被认为是"开始的".在此情况下,service会一直运行,直到service使用stopSelf()停止它自己或另外的组件调用了stopService()停止了它,不管是否有客户端绑定了它.
另外,如果你的service已经启动并且接受绑定,那么当系统调用你的onUnbind()方法,你可以选择返回true表示你想在客户端下一次绑定到service时接受一个对onRebind()的调用(而不是一个对onBind()的调用).onRebind()返回void,但是客户端依然会在它的onServiceConnected()回调中接收到IBinder.下图演示了这种生命其的逻辑:

图1.一个已开始并已绑定的service的生命期
Android ServiceConnection的更多相关文章
- Android ServiceConnection类的onServiceDisconnected(ComponentName name)在什么时候执行
ServiceConnection类中的两个方法非别在服务连接成功时.不成功时调用.其中onServiceDisconnected()方法在连接正常关闭的情况下是不会被调用的, 该方法只在Servic ...
- (原)android系统下绑定Server的时候报MainActivity has leaked ServiceConnection的错误
今天在android系统下根据官方的demo代码,我们需要启动一个服务,并绑定,但在程序启动以后,老是报错: Activity MainActivity has leaked ServiceCon ...
- Android Exception 12(has leaked ServiceConnection)
09-09 15:12:31.154: E/ActivityThread(18855): Activity com..xxx.xx.act.LoadingAct has leaked ServiceC ...
- 【起航计划 034】2015 起航计划 Android APIDemo的魔鬼步伐 33 App->Service->Local Service Binding 绑定服务 ServiceConnection Binder
本例和下列Local Service Controller 的Activity代码都定义在LocalServiceActivities.Java 中,作为LocalServiceActivities ...
- Android Service com.android.exchange.ExchangeService has leaked ServiceConnection
启动Android项目的时候,clean Project的时候,报错: android.app.ServiceConnectionLeaked: Service com.android.exchan ...
- Android探索之AIDL实现进程间通信
前言: 前面总结了程序间共享数据,可以使用ContentProvider也可以使用SharedPreference,那么进程间怎么共享内存呢?Android系统中的进程之间不能共享内存,因此,需要提供 ...
- Android—Service与Activity的交互
service-Android的四大组件之一.人称"后台服务"指其本身的运行并不依赖于用户可视的UI界面 实际开发中我们经常需要service和activity之间可以相互传递数据 ...
- Android之使用Bundle进行IPC
一.Bundle进行IPC介绍 四大组件中的三大组件(Activity.Service.Receiver)都是支持在Intent中传递Bundle数据的,由于Bundle实现了Parcelable接口 ...
- Android之使用文件进行IPC
一.文件进行IPC介绍 共享文件也是一种不错的进程间通信方式,两个进程通过读/写同一个文件来交换数据.在Windows上,一个文件如果被加了排斥锁将会导致其他线程无法对其进行访问,包括读写,而由于An ...
随机推荐
- C# String 前面不足位数补零的方法 PadLeft
PadLeft(int totalWidth, char paddingChar) //在字符串左边用 paddingChar 补足 totalWidth 长度PadLeft(int totalWid ...
- Docker Machine, Compose, and Swarm: How They Work Together
The three tools are now neatly packaged into what’s called the Docker Toolbox. Docker Machine1/ crea ...
- 第零篇、HTML5简介
1.什么是HTML5? 背景:互联网的快速兴起 1>网页5.0版本 2>2014年才定制HTML5标准 3>移动先行 2.为什么要使用HTML5? 1>跨平台(可以运行所有的浏 ...
- Podfile 文件的编写
# Uncomment this line to define a global platform for your projectplatform :ios, '9.0' target 'Cocoa ...
- (转)TCP注册端口号大全
分类: 网络与安全 cisco-sccp 2000/tcp Cisco SCCPcisco-sccp 2000/udp Cisco SCCp# Dan Wing <dwing&cisco ...
- 问题解决:form表单的button按钮问题
最近写了一个KendoUI 的kendowindow组件,组件里包含了一个form表单,表单里有一个button,不是提交保存的按钮,而是链接到另一个kendowindow的按钮,跟请求提交毫无关系, ...
- 踩过的坑系列之InputStream.read(byte[])方法
项目之前都是好好的,最近现场那边出现一个问题,报错不是合法的json字符串,这个json字符串是通过http请求访问获得的. 通过直接在浏览器上直接访问http这个请求,发现返回的json也是完全正确 ...
- java感触一则
看到开源中国上边有那么多关于java的开源项目,从数据库到3D游戏再到IDE工具,甚至有iQQ,形形种种都是一些比较成熟的,工程很大的项目.才意识到Java是如此的强大和流行. 这么多开源的代码我不可 ...
- javascript操作html元素CSS属性
下面先记录一下JS控制CSS所使用的方法. 1.使用javascript更改某个css class的属性... <style type="text/css"> .ori ...
- Anagrams问题
#include<stdio.h> #include<string.h> int main() { int i; ],word2[]; //分别用于存储输入的两个单词 int ...