首页 > 编程知识 正文

android后端(binder机制面试)

时间:2023-05-03 12:09:16 阅读:75934 作者:2959

文章目录一、Binder一次复制二、文件写入流程三、 AIDL1.3.1代码结构1.3.2 ibook manager1.3.3stub1.3.4proxy1.3. 5a IDL调用1.3.5.1活动和服务同进程1.3.5.5 ger.add1.3.6.4stub.ontransact、Activity.bindService五、iivice五

一、Binder一次复制

内核空间1共享与用户空间2相同的物理存储器,用户空间1的数据data被复制到内核空间1,内核空间1的数据data被映射到物理存储器,并且用户空间2可以直接从共享的物理存储器获取数据data

二、文件写入过程的传统方式:将数据写入磁盘需要复制两次,使用mmap后一次,将数据写入磁盘一次

三. AIDL undo: 跨进程时BinderProxy与Stub的关系

1.3.1代码结构1.ibook manager2. stub3. proxy1.3.2ibookmanagerinterfaceibookmanager { void add (} 1.3.3 stubpublicstaticabstractclassstubextendsandroid.OS.binderimplementscom.module.MST.ibook manager {私有服务器} public static com.module.MST.ibookmanagerasinterface (Android.OS.ibinderobj ) if ) () obj==null ) ) { return nn if () ) (iin!=null (iininstanceofcom.module.MST.ibook manager ) ) return ((com.module.MST.ibook manager ) iin ); } return newcom.module.MST.ibook manager.stub.proxy (obj; } @ overridepublicandroid.OS.ibinderasbinder () { return this; } @ overridepublicbooleanontransact (intcode,android.os.Parcel data,android.os.Parcel reply,int flags ) throws and int flags ) throws andr sitch (代码) casetransaction_add: ) data.enforce interface (descriptor ); this.add (; reply.writenoexception (返回真; } } staticfinalinttransaction _ add=(Android.OS.I binder.first _ call _ transaction0); }1.3.4proxyprivatestaticclassproxyimplementscom.module.MST.ibook manager { private Android.OS.ibindermremote; proxy(Android.OS.Ibinderremote ) {mRemote=remote; } @ overridepublicandroid.OS.ibinderasbinder () { return mRemote; } @ overridepublicvoidadd (throws Android.OS.remote exception ) Android.OS.parcel _ data=Android.OS.parcel.OS

n(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); boolean _status = mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0); if (!_status && getDefaultImpl() != null) { getDefaultImpl().add(); return; } _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } public static com.module.mst.IBookManager sDefaultImpl;} 1.3.5 AIDL调用 Activity {bindService(Intent(this, AidlService::class.java), MyConn(), 1)inner class MyConn : ServiceConnection { override fun onServiceConnected(name: ComponentName?, service: IBinder?) { mBinder = IBookManager.Stub.asInterface(service) Log.v("AndroidTest", "[onServiceConnected][process = ${Process.myPid()}, " + "service = $service, " + "mBinder = $mBinder}]") } override fun onServiceDisconnected(name: ComponentName?) { } }}Service {override fun onBind(intent: Intent?): IBinder? { Log.v("AndroidTest", "[AidlService][onBind][binder = $binder, process = ${Process.myPid()}]") return binder } private var binder: Stub = object : Stub() { override fun add() { Log.v("AndroidTest", "[binder][add][process = ${Process.myPid()}]") } }} 1.3.5.1 Activity与Service同进程 日志:mainProcess = 15662[AidlService.onBind][process = 15662]{binder = AidlService$binder$1@adbf1c4}[onServiceConnected][process = 15662]{service = AidlService$binder$1@adbf1c4, mBinder = .AidlService$binder$1@adbf1c4}[binder.add][process = 15662]

总结: 当Activity与Service在一个进程时, Service.onBind与onServiceConnected()返回的IBinder对象为同一个, 都指向的是Stub实例

1.3.5.2 Activity与Service不同进程 mainProcess = 17087[AidlService.onBind][process = 17317]{binder = AidlService$binder$1@410f6d6}[onServiceConnected][process = 17087]{ service = android.os.BinderProxy@4e7d8ad, mBinder = IBookManager$Stub$Proxy@d8a27e2}[binder.add][process = 17317]

总结: Activity和Service不在同一个进程中, Service.onBind返回Stub对象, 而onServiceConnected返回 BinderProxy, 并且此时onBind与onServiceConnected不在同一个进程中, 同时add与Service在同一个进程中.

1.3.6 AIDL调用流程

1.3.6.1 new Stub public Stub() {// DESCRIPTOR = "com.module.mst.IBookManager"; this.attachInterface(this, DESCRIPTOR);}public void attachInterface(IInterface owner, String descriptor) { mOwner = owner; mDescriptor = descriptor;} 1.3.6.2 Stub.asInterface

根据调用是否属于同进程返回不同的实例对象, 同进程返回 Stub, 不同进程返回 BinderProxy.

public static com.module.mst.IBookManager asInterface(android.os.IBinder obj) {if ((obj == null)) {return null;}// 1.同进程返回obj.mOwner即objandroid.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin != null) && (iin instanceof com.module.mst.IBookManager))) {return ((com.module.mst.IBookManager) iin);}// 2.不同进程返回obj<BinderProxy>的代理对象Proxyreturn new com.module.mst.IBookManager.Stub.Proxy(obj);} 1.3.6.3 IBookManager.add // 同进程:IBookManager.add() -> StubImpl.add()// 不同进程:IBookManager.add() -> Proxy.add()@Overridepublic void add() throws android.os.RemoteException {//1.写数据载体android.os.Parcel _data = android.os.Parcel.obtain();//2.读数据载体android.os.Parcel _reply = android.os.Parcel.obtain();int _result;try {_data.writeInterfaceToken(DESCRIPTOR);//3.mRemote = BinderProxy, 即远程<Service进程>Stub的代理对象,//该方法触发远端Stub.onTransact的执行 boolean _status = mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0); _reply.readException(); //4.同步阻塞读取数据 _result = _reply.readInt();} finally {_reply.recycle(); _data.recycle();}//5.返回数据return _result;} 1.3.6.4 Stub.onTransact @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags){java.lang.String descriptor = DESCRIPTOR;switch (code){ case TRANSACTION_add: { data.enforceInterface(descriptor); // this.add() -> StubImpl.add(); int _result = this.add(); reply.writeNoException(); // 写数据 reply.writeInt(_result); return true; }}} 四、Activity.bindService

Activity.bindService获取到Service进程所在的IBinder跨了6次进程.

1、客户端通过AMS获取服务端的IBinder对象, 进行了3次跨进程通信2、服务端通过AMS将服务端的Binder对象返回给客户端, 进行了3次跨进程通信

五、Intent传值



内存被操作系统划分为两块: 用户空间和内核空间, 用户空间是用户程序代码运行的地方, 内核空间是内核代码运行的地方, 为了安全, 它们是隔离的, 即使用户的程序崩溃了, 内核也不受影响.

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。