美文网首页
IPC机制(三)——AIDL

IPC机制(三)——AIDL

作者: 李die喋 | 来源:发表于2019-10-08 22:59 被阅读0次

    在看Binder的时候就非常好奇AIDL这个神奇的东西,为什么我写了.aidl文件,AS就自动生成了与它对应的文件,而且还实现它里面的方法。首先还是要知道AIDL是什么。。。

    关于AIDL

    AIDL,英文全称:Android Interface Definition Language。很直白的翻译的话就是安卓接口定义语言。它是一种语言,可以拿来生成用于IPC的代码。其实,可以把AIDL理解称为一个模板,在使用中,实际上起作用的不是AIDL代码,而是根据它生成的一个IInterface实例的代码。

    在AIDL文件中并不是所有的数据类型都是可以使用的。下面是它可以使用的数据类型:

    • 基本数据类型:int short long float double byte boolean char
    • String和CharSequence
    • List:只支持ArrayList,里面的每个元素都必须能够被AIDL支持
    • Map:只支持HashMap,里面的每个元素都必须能够被AIDL支持,包括key和value
    • Parcelable:所有实现了Parcelable接口的对象
    • AIDL:所有的AIDL接口本身也可以在AIDL文件中使用

    注意

    • 自定义的Parcelable对象和AIDL对象必须要显式import进来
    • 如果AIDL文件中用到了自定义的Parcelable对象,那么必须新建一个和它同名的AIDL文件,并在其中声明为Parcelable类型
    • AIDL中除了基本数据类型,其它类型必须标上方向
      • in 输入型参数
      • on 输出型参数
      • inout 输入输出型参数
    • AIDL接口中只支持方法,不支持声明静态变量。

    AIDL进程间通信

    • 远程服务端
    public class BookManagerService extends Service {
        private static final String TAG = "BMS";
        //支持并发读/写,可以进行自动的线程同步
        private CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<>();
        
         private Binder mBinder = new IBookManager.Stub() {
            @Override
            public List<Book> getBookList() throws RemoteException {
                return mBookList;
            }
    
            @Override
            public void addBook(Book book) throws RemoteException {
                mBookList.add(book);
            }
    
        }
        
        @Override
        public void onCreate() {
            super.onCreate();
            mBookList.add(new Book(1,"Android"));
            mBookList.add(new Book(2,"Web"));
    
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            Log.e(TAG,"onBind()");
            return mBinder;
        }
    }
    

    实现步骤:

    • 通过IBookManager.Stub创建Binder对象,实现IBookManager接口中的两个方法getBookList和addBook
    • onBind方法返回IBinder对象

    这里用到了CopyOnWriteArrayList,刚才说AIDL支持的数据类型List只支持ArrayList,但CopyOnWriteArrayList并不继承于持ArrayList。因为AIDL支持的是抽象的List,且List只是一个接口。Binder会按照List的规范去访问数据并最终形成一个ArrayList传递给客户端。相似的还有ConcurrentHasMap

    客户端实现

    public class MainActivity extends AppCompatActivity {
        private static final String TAG = "MainActivity";
    
        private ServiceConnection mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                IBookManager bookManager = IBookManager.Stub.asInterface(service);
    
                try {
                    List<Book> bookList = bookManager.getBookList();
                    Log.e(TAG,"query book list,list type:"+bookList.getClass().getCanonicalName());
                    Log.e(TAG,"query book list:"+bookList.toString());
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
    
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Intent intent = new Intent(this,BookManagerService.class);
            bindService(intent,mServiceConnection, Context.BIND_AUTO_CREATE);
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            unbindService(mServiceConnection);
        }
    }
    

    实现步骤:

    • 首先和服务端绑定bindService
    • 通过服务端传递的IBinder对象,根据IBookManager中判断是本地还是远程的asInrterface方法,创建IBookManager对象
    • 通过IBookManager,操作目标方法

    参考文章

    Binder深入分析

    相关文章

      网友评论

          本文标题:IPC机制(三)——AIDL

          本文链接:https://www.haomeiwen.com/subject/cooipctx.html