美文网首页
Android Aidl使用

Android Aidl使用

作者: 北疆小兵 | 来源:发表于2018-04-21 11:47 被阅读0次

    简介

    在android中,常常一个应用需要和另外一个应用进程跨进程通信,这就不可避免地涉及到了跨进程通信。android有种多种方式可以达到跨进程通信的目的,例如文件共享,Bundle,Messenger,Aidl。文件共享存在并发读写的问题,Bundle传递参数只能局限于基本数据类型以及实现了Parceable或者Serializable接口的对象 ,本文主要介绍Aidl跨进程通信

    客户端实现

    • 定义一个实体类实现Parcelable接口
    
    public class Book implements Parcelable {
    
        public int bookId;
    
        public String bookName;
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(this.bookId);
            dest.writeString(this.bookName);
        }
    
        public Book() {
        }
    
        public Book(int bookId, String bookName) {
            this.bookId = bookId;
            this.bookName = bookName;
        }
    
        protected Book(Parcel in) {
            this.bookId = in.readInt();
            this.bookName = in.readString();
        }
    
        public static final Parcelable.Creator<Book> CREATOR = new Parcelable.Creator<Book>() {
            @Override
            public Book createFromParcel(Parcel source) {
                return new Book(source);
            }
    
            @Override
            public Book[] newArray(int size) {
                return new Book[size];
            }
        };
    
    
    • 定义一个Book.aidl类
    package com.apache.android.aidl;
    
    parcelable Book;
    
    
    • 定义接口通信aidle文件
    interface IBookManager {
    
       List<Book> getBookList();
    
       void addBook(in Book book);
    }
    

    注意这里有一个坑,就是这里将Book.java和Book.aidl是同在aidl目录下的(出于方便移植的目的 ),但是android studio在编译的时候会报错,提示找不到Book.java类, 原因是Android Studio 是使用gradle来构建项目的,而Gradle构建项目的时候会通过SourceSet来配置不同的访问路径,从而加快查找速度-问题就出在这里,Gradle 默认是将java代码的访问路径放在java目录下的,这样一来如果java代码放在aidl目录下,gradle自然就找不到这个java文件了,解决办法是在gradle中把aidl目录也配置到sourceSet中去

     sourceSets{
            main{
                java.srcDirs = ['src/main/java', 'src/main/aidl']
            }
        }
    

    远程服务端实现

    定义一个BookManagerService服务,在manifest清单文件中配置为 remote进程

    public class BookManagerService extends Service {
        private CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<>();
    
        @Override
        public void onCreate() {
            super.onCreate();
            mBookList.add(new Book(1,"android"));
            mBookList.add(new Book(2,"ios"));
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return binder;
        }
    
        private IBinder binder = new IBookManager.Stub() {
            @Override
            public List<Book> getBookList() throws RemoteException {
                return mBookList;
            }
    
            @Override
            public void addBook(Book book) throws RemoteException {
                mBookList.add(book);
            }
        };
    }
    

    创建一个IBinder对象并在onBinder方法中返回,这个对象继承自IBookManager.Stub,并实现它内部的Aidl方法

    客户端使用

    客户端使用就比较简单了, 绑定远程服务,绑定成功后将服务端返回的Binder对象转换成Aidlj可口,然后就可以通过这个接口去调用服务器端的方法了

    
         Intent intent = new  Intent(this,BookManagerService.class);
        bindService(intent,connection, Context.BIND_AUTO_CREATE);
        
    
        private ServiceConnection connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                NLog.d(TAG, "onServiceConnected");
    
                manager = IBookManager.Stub.asInterface(service);
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                NLog.d(TAG, "onServiceDisconnected");
                manager = null;
            }
        };
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            unbindService(connection);
        }
    
    
    
    
        private void addBook(){
            try {
                if (manager == null){
                    return;
                }
                Book book = new Book(mCount.getAndAdd(1), "Android进阶: "+mCount.get());
                manager.addBook(book);
                printBookList();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    
    

    相关文章

      网友评论

          本文标题:Android Aidl使用

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