代理类内容 :
private static class Proxy implements kim.hsl.aidl_demo.IMyAidlInterface { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(anInt); _data.writeLong(aLong); _data.writeInt(((aBoolean)?(1):(0))); _data.writeFloat(aFloat); _data.writeDouble(aDouble); _data.writeString(aString); boolean _status = mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0); if (!_status && getDefaultImpl() != null) { getDefaultImpl().basicTypes(anInt, aLong, aBoolean, aFloat, aDouble, aString); return; } _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } /** * in 写入, out 输出, inout 写入和输出 */ @Override public void addStudent(kim.hsl.aidl_demo.Student student) throws android.os.RemoteException { // 通过 Parcel 池获得两个对象 , 分别用于输入和输出 // 输入对象 android.os.Parcel _data = android.os.Parcel.obtain(); // 输出对象 android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); if ((student!=null)) { _data.writeInt(1); student.writeToParcel(_data, 0); } else { _data.writeInt(0); } // 调用 Binder 的 transact 方法 boolean _status = mRemote.transact(Stub.TRANSACTION_addStudent, _data, _reply, 0); if (!_status && getDefaultImpl() != null) { getDefaultImpl().addStudent(student); return; } _reply.readException(); if ((0!=_reply.readInt())) { student.readFromParcel(_reply); } } finally { _reply.recycle(); _data.recycle(); } } /** * 获取 Student 集合 */ @Override public java.util.List<kim.hsl.aidl_demo.Student> getStudents() throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); java.util.List<kim.hsl.aidl_demo.Student> _result; try { _data.writeInterfaceToken(DESCRIPTOR); boolean _status = mRemote.transact(Stub.TRANSACTION_getStudents, _data, _reply, 0); if (!_status && getDefaultImpl() != null) { return getDefaultImpl().getStudents(); } _reply.readException(); _result = _reply.createTypedArrayList(kim.hsl.aidl_demo.Student.CREATOR); } finally { _reply.recycle(); _data.recycle(); } return _result; } public static kim.hsl.aidl_demo.IMyAidlInterface sDefaultImpl; }
Binder 的 transact 方法 ; 进入该方法后 , 会将原来的线程挂起 , 直到返回 , 原来的线程才会继续执行 , 这里非常容易出现 ANR ;
/** * 远程对象的基类,由{@link IBinder}定义的轻量级远程过程调用机制的核心部分。 * 此类是IBinder的一个实现,它提供了此类对象的标准本地实现。 * * <p>大多数开发人员不会直接实现这个类, * 而是使用<a href=“{@docRoot}guide/components/aidl.html”>aidl</a>工具来描述所需的接口, * 让它生成适当的Binder子类。 * 然而,您可以直接从Binder派生来实现您自己的定制RPC协议, * 或者直接实例化一个原始Binder对象,将其用作可以跨进程共享的令牌。 * * <p>这个类只是一个基本的IPC原语; * 它对应用程序的生命周期没有影响,并且只有创建它的进程继续运行时才有效。 * 要正确使用此功能,您必须在顶级应用程序组件(a{@link android.app.Service}、 * {@link android.app.Activity}或{@link android.content.ContentProvider}) * 的上下文中执行此操作,该组件应保持运行。</p> * * <p>您必须记住流程可能会消失的情况,因此需要稍后重新创建新的活页夹, * 并在流程再次启动时重新附加它。 * 例如,如果您在{@link android.app.Activity}中使用此函数, * 则您的活动的进程可能会在活动未启动时被终止; * 如果以后重新创建活动,则需要创建新的活页夹, * 并再次将其交回正确的位置; * 您需要注意的是,您的流程可能由于其他原因(例如接收广播)而启动, * 这将不涉及重新创建活动,因此运行其代码以创建新的绑定。</p> * * @see IBinder */ public class Binder implements IBinder { /** * 默认实现回放地块并调用onTransact。在远程端,transact调用绑定器来执行IPC。 */ public final boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException { if (false) Log.v("Binder", "Transact: " + code + " to " + this); if (data != null) { data.setDataPosition(0); } boolean r = onTransact(code, data, reply, flags); if (reply != null) { reply.setDataPosition(0); } return r; } }