android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection public static final String TAG = "MainActivity"; private IMyAidlInterface aidl; private ServiceConnection serviceConnection = new ServiceConnection() { /** * 传入需要的 Service , 让系统寻找指定的远程服务 public static final String TAG = "MainActivity"; private IMyAidlInterface aidl; private ServiceConnection serviceConnection = new ServiceConnection() { /** * 传入需要的 Service , 让系统寻找指定的远程服务
ContextImpl.java public boolean bindService(Intent service, ServiceConnection conn, int flags) { 要注意的是bind连接回调ServiceConnection是引用类型,因为bindService可能是跨进程的,需要先将其转换为bind接口IServiceConnection,具体实现为ServiceDispatcher 接下看connect的具体过程: 在前面ContextImp.bindServiceCommon中已经知道,传递到AMS中的ServiceConnection是经过包装的IServiceConnectionBinder 如此ServiceConnection已进行了其他连接,则先断开原有连接; 此场景出现在: 1)unbindService,具体过程下面分析; 2)用同一个ServiceConnection去bind 新连接建立完成,回调ServiceConnection.onServiceConnected 至此,一次bind连接已经完成,之后启动方就可以通过连接成功后返回的IBinder对象与Service进行交互了
(): List<User> { //... } } //usage SQLiteSingleton.getAllUsers() 4、Object expression Java 匿名类 ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName Override public void onServiceConnected(ComponentName name, IBinder service) { //... } } Kotlin 匿名类 val serviceConnection = object: ServiceConnection { override fun onServiceDisconnected(name: ComponentName?)
通过 bindService(Intent intent ,ServiceConnection connetion,int flag) 启动 Service 后 Service 的正常的生命周期是:onCreate Activity 在没有 bindService 的情况下,调用 unBindService(ServiceConnection serviceConnection) 是会 crash 的。 因为执行完一次 Service就不再注册 serviceConnection 了,再次 unBinderService 就会出现错误 Service not registered:MainActivity $ServiceConnection$只有在单独执行 bindService (执行 bindService 前后没有执行 startService)的情况下,执行 unBindService 才会正常执行 关于 binSerive(Intent intent,ServiceConnection connection,int flag) 中的参数 第一个参数就是要绑定的 Service 的intent 就不多说了
Context的bindService()方法 bindService(Intent service, ServiceConnection conn, int flags) (1)service 指定需要启动的Service (2)conn是一个ServiceConnection对象,这个对象用于监听访问者和Service之间的连接情况。 当访问者与Service之间连接成功之后会回调ServiceConnection对象的onServiceConnected(ComponentName name, IBinder service)方法, 当Service所在的宿主进程异常中断或其他原因停止的时候,会回调ServiceConnection对象的onServiceDisconnected(ComponentName name)方法。 ServiceConnection对象的onServiceConnected()方法中有一个IBinder对象,这个对象可实现与被绑定的Service之间的通信。
调用时,必须提供ServiceConnection的实现,后者会监控与服务的连接,当Android系统创建客户端与服务之间的连接时,会对ServiceConnection回调onServiceConnected @Override public IBinder onBind(Intent arg0) { return sBinder; } 客户端绑定到服务步骤: 1.实现ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName ; /** * Class for interacting with the main interface of the service. */ private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className
4)onBind()返回mybinder对象: public IBinder onBind(Intent intent) { return myBinder; } 5)通过serviceconnection 获取Binder对象进一步来获取service对象,最后调用service中的方法: ServiceConnection conn = new ServiceConnection() { savedInstanceState); setContentView(R.layout.activity_main); initEvent(); } ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName
接着上一篇,本文就解决《篇Binder详解》末尾抛出的问题,也就是如下的问题: 我们客户端(即MainActivity)接受远程对象是在自己重写的ServiceConnection的onServiceConnected ()方法中接收的,那么系统是何时对ServiceConnection的onServiceConnect()方法进行回调的呢? ,那我们的分析自然是从ContextImpl的bindService()开始了,上代码: @Override public boolean bindService(Intent service, ServiceConnection * @param flags * @param user * @return */ private boolean bindServiceCommon(Intent service, ServiceConnection 在ServiceDispatcher的构造方法中就会根据我们bindService()时传入的ServiceConnection实例创建InnerConnection,最后在方法的结尾,调用ServiceDispatcher
,这需要重写onServiceConnected()和onServiceDisconnected()两个回调函数 private ServiceConnection sc = new ServiceConnection stub super.onStop(); if(bound){ bound = false; unbindService(connection); } } private ServiceConnection connection = new ServiceConnection(){ @Override //客户端使用IBinder来实例化Messenger,然后使用它来发送Message对象到服务 ,这需要重写onServiceConnected()和onServiceDisconnected()两个回调函数 调用bindService()方法,传递ServiceConnection实现 当系统调用 ServiceConnection时,可以使用接口定义的方法回调服务 调用unbindService()方法解除绑定 三、Service生命周期 可参考这篇文章:service生命周期
, Process.myUserHandle()); } private boolean bindServiceCommon(Intent service, ServiceConnection } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } 该方法中首先将ServiceConnection 转换成ServiceDispatcher.InnerConnection对象,由于ServiceConnection不能进行跨进程,而他必须通过binder让远程服务调用自己方法,而InnerConnection public final IServiceConnection getServiceDispatcher(ServiceConnection c, Context context 是运行在主线程中的,RunConnection也是调用了ServiceDispatcher的doConnected方法,由于内部保存了客户端的ServiceConnection对象,所以方便调用onServiceConnected
在上文的使用方法中已经提到了bindService()使用到的参数,Intent、ServiceConnection、Int。 ServiceConnection /** * bindService()方法中的参数之一。 * 用于对service进行操作 */ ServiceConnection connection = new ServiceConnection() { // Activity和 必须要调用的unbindService(ServiceConnection)。 Q1:为什么我们一定要调用这个方法,如果我们不解绑会出现什么样的问题? 也就是说ServiceConnection内存泄漏了。这也是为什么我们一直说需要解绑的原因。
conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName 方法,得到IBinder类型的实例,将该方法作为参数传入client端的ServiceConnection的onServiceConnected方法中,onServiceConnected方法的执行表明 创建ServiceConnection类型的实例,并重写其onServiceConnected方法和onServiceDisconnected方法。 2. 当我们调用bindService方法时,我们需要将Intent、ServiceConnection等实例传入,Intent包含了我们要绑定的Service,ServiceConnection我们在上面提到过
使用多个ServiceConnection对象Bind同一个Service ServiceConnection其实也是一个Service,提供给AMS维护,用于管理目标Service的回调。 同一个ServiceConnection对象可以管理多个Service,Client端已做到对不同Service的复用,AMS仅维护一个IServiceConnection;但不同ServiceConnection 使用多个ServiceConnection对象Bind同一个Service的影响: 增加AMS的维护负担,Service的启动/退出都会持有AMS锁后遍历SC; 长时间持有AMS锁,导致整机卡顿。 优化建议: 复用同一个ServiceConnection对象,特别是同一个Service; 监听Service的死亡回调,若有需要可立即重新Bind; 及时unbind不再使用的Service。
IMessage message ) 示例代码: public static async sendMessage(content: Message): Promise<string> { const serviceConnection = AzureServiceBus.createConnection(); const client = serviceConnection.createQueueClient("" + process.env.AZURE_SERVICEBUS_QUEUE JSON.stringify(content), label: "MyTopic"}); await client.close(); } catch (error) { } finally { await serviceConnection.close = AzureServiceBus.createConnection(); const client = serviceConnection.createQueueClient( "" + response = sequenceId.toString(); await client.close(); } catch (error) { } finally { await serviceConnection.close
四、绑定Service 绑定Service用是通过调用bindService(Intent service, ServiceConnection conn, int flags)方法来实现的,单看参数就知道与启动 另外,Service和其他组件的链接表示为一个ServiceConnection,要想一个Service和其他组件绑定,需要实现一个新的ServiceConnection,建立一个链接后,就可以通过重写 代码如下: 1 MyService.MyBinder binder = null; 2 class MyServiceConn implements ServiceConnection { 3 null; 14 } 15 } 第三步:调用bindService执行绑定Service 要想绑定需要给bindService()除了需要给他传递一个需要的Intent和一个ServiceConnection unbindService(myServiceConn); 6 } 7 } 8 }); 这里需要注意的是,unbindService方法中传入的ServiceConnection
, int)方法启动该Service 4.不再使用时,调用unbindService(ServiceConnection)方法停止该服务 使用这种bind方式启动的Service的生命周期如下: onCreate myConn);// 如果onDestroy再解绑,解绑多次报异常 } // 定义一个类,用来监视服务的状态 private class MyConn implements ServiceConnection 如果返回null,那么ServiceConnection的onNullBinding()方法将被调用,而不是onServiceConnected(). conn ServiceConnection:在服务启动和停止时接收信息。这必须是一个有效的ServiceConnection对象;它不能是NULL。 flags int:绑定的操作选项。 如果此值是true,你以后应该调用unbindService(ServiceConnection)释放连接。
是得不到上下文的 通过bindService()方法,可以间接建立对Service对象的关系 bindService(service,conn,flags),参数:service是Intent对象,conn是ServiceConnection 对象中间人不能为空,选项BIND_AUTO_CREATE,如果不存在就创建 ServiceConnection类是个接口,创建一个内部类MyConn实现这个接口 两个实现方法onServiceConnected android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection setContentView(R.layout.activity_main); } // 联系代理人的纽带 private class MyConn implements ServiceConnection
bindService(new Intent("com.turing.base.activity.service.aidl.AIDLService"), serviceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected 对象,创建ServiceConnection对象的过程中如果绑定成功,系统会调用ServiceConnection.onServiceConnected方法,通过改方法的service参数值可以获得AIDL serviceConnection = new ServiceConnection() { @Override public void onServiceConnected bindService(new Intent("mobile.android.ch12.complex.type.aidl.IMyService"), serviceConnection
setContentView(R.layout.activity_main); bindService(new Intent(this, WebSocketService.class), serviceConnection } @Override protected void onDestroy() { super.onDestroy(); unbindService(serviceConnection ); } private ServiceConnection serviceConnection = new ServiceConnection() { @Override
conn , int flags); 参数说明: 第一个参数表示与服务相关联的Intent对象 第二个参数的类型是ServiceConnection,负责连接Intent对象指定的服务,通过ServiceConnection 的实例并传 给bindService().ServiceConnection包含一个回调方法,系统调用这个方法来传递要返回的IBinder. 所以,从你的客户端绑定到一个service,你必须: 1实现ServiceConnection. serviceConnection = new ServiceConnection() { /** * 成功连接服务后,改方法被调用,在该方法中可以获得MyService_BindService ServiceConnection.onServiceConnected方法的第二个参数是一个IBinder类型的变量,将该参数转换成MyService_BindService .MySBinder对象