Binder总结-使用篇

xiaoxiao2025-06-04  55

Binder不用多说,Android的核心机制之一,用于进程间通信,更加安全,只进行一次拷贝数据。

1.创建aidl文件

package com.example.davidzhaodz.myapplication; // Declare any non-default types here with import statements interface IMyAidlInterface { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString); void add(int a, int b); //这个是你要使用的函数 }

2.创建service,这里面实现了add。IMyAidlInterface.Stub是as编译aidl文件自动生成的

public class TestService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return mIBinder; } private final IBinder mIBinder = new IMyAidlInterface.Stub() { @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { } @Override public void add(int a, int b) throws RemoteException { Log.e("david", "test add - remote"); } }; }

3.关于自动生成的IMyAidlInterface.java

主要有两个内部类Stub和Proxy,其实这两个类是真正用于binder通信的。多说两句,其实client对server的访问时分两种的,一种是在同一个进程,这时候binder直接通信,不需要代理。第二种是,在不同的进程,这时server端的是binder的代理,是真的要通过binder驱动进行跨进程通信了

public static com.example.davidzhaodz.myapplication.IMyAidlInterface asInterface(android.os.IBinder obj) { if ((obj==null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin!=null)&&(iin instanceof com.example.davidzhaodz.myapplication.IMyAidlInterface))) { return ((com.example.davidzhaodz.myapplication.IMyAidlInterface)iin);//本地接口 } return new com.example.davidzhaodz.myapplication.IMyAidlInterface.Stub.Proxy(obj);//返回代理 }

其实这里些播放器用aidl。有人说是大炮打蚊子,其实只是看起来大炮打蚊子,实际逻辑并不是这样,因为有这样的逻辑判断

4.在你的activity里bindservice,调用函数。别忘了service添加到manifest

private void testService() { Log.e("david", "testService"); Intent intent = new Intent(this, TestService.class); bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); } private IMyAidlInterface mIMyAidlInterface; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(service); try { mIMyAidlInterface.add(3, 4); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { } };

一个基本的binder调用就基本完成了

题外话:

1.service为什么有onBind,想了想,其实service就是通过binder来进行通信的,可以跨进程,可以是同一个进程

2.不用aidl怎么实现。看一下IMyAidlInterface.java,就知道了。最主要的Stub,就是继承了Binder,实现了接口。如果自己来写,也只要继承Binder,实现接口,同时注意需要实现onTransact,是最重要的。这里有个重要区别,本地Binder是onTranscat,而代理调用Trancat,也就是说onTrancat是在服务端的(返回数据),Trancat是在客户端(发送数据)。看代码理解。

3.从framework来说,应用调用系统服务,wms/ams/ims都是跨进程调用,因为这些系统服务是属于systemserver的.同样看源码可以知道,这些系统服务都是按照binder调用来写的,而且为了便于app调用,framework有时把client端的接口实现也写好了,所以有时我们调用起来,感觉不到binder

网上有个不错的例子 https://github.com/yuanhuihui/BinderSample 他把app/framework/native都谢了例子

转载请注明原文地址: https://www.6miu.com/read-5031248.html

最新回复(0)