IPC进程间通信:AIDL

上篇文章使用了Messenger来进行进程间通信,其本质也是使用AIDL。

这次service端模拟一个图书馆,Activity模拟一位读者,读者可以查看图书馆中的图书列表,可以添加图书,当有新图书加入时通知读者(即添加Listener)

添加新进程中的service

     

AIDL支持的数据类型:

1.AIDL支持Java原始数据类型。

2.AIDL支持String和CharSequence。

3.实现了Parcelable接口的实例。

4.AIDL支持java.util.List和java.util.Map,但是有一些限制。集合中项的允许数据类型包括Java原始类型、String、CharSequence或是android.os.Parcelable。无需为List和Map提供import语句,但需要为Parcelable提供import语句。

5.非原始类型中,除了String和CharSequence以外,其余均需要一个方向指示符。方向指示符包括in、out、和inout。in表示由客户端设置,out表示由服务端设置,inout表示客户端和服务端都设置了该值。

Book封装类,这里需要实现Parcelable接口来实现序列化,在Android studio中可以快速生成,并且实现Parcelable中的方法

public class Book implements Parcelable {
    private int id;
    private String name;

    protected Book(Parcel in) {
        id = in.readInt();
        name = in.readString();
    }

    public Book(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public static final Creator CREATOR = new Creator() {
        @Override
        public Book createFromParcel(Parcel in) {
            return new Book(in);
        }

        @Override
        public Book[] newArray(int size) {
            return new Book[size];
        }
    };


    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(id);
        dest.writeString(name);
    }

   ...省略get/set方法
}

这里开始编写AIDL文件,android studio中可以右键新建AIDL文件。

如果AIDL中使用到了自定义的Parcelable对象,需要新建一个同名的aidl文件,声明它为Parcelable类型,并且他们的包结构是相同的。

IPC进程间通信:AIDL_第1张图片

// Book.aidl
package com.du.ipc.bean;

parcelable Book;

用来监听添加书籍的Listener的aidl代码:

// IOnBookChangeListener.aidl
package com.du.ipc;

import com.du.ipc.bean.Book;

interface IOnBookChangeListener {
     void onChangeBook(in Book book);
}

BookManager.aidl代码:

// IBookManager.aidl
package com.du.ipc;
import com.du.ipc.bean.Book;
import com.du.ipc.IOnBookChangeListener;

interface IBookManager {

    List getBookList();
    void addBook(in Book book);
    void registListener(IOnBookChangeListener listener);
    void removeListener(IOnBookChangeListener listener);
}

Activity代码如下:

public class BookActivity extends AppCompatActivity {
    private int bookId = 1;
    private IBookManager bookManager;
//    Service连接
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
//            连接成功
            bookManager = IBookManager.Stub.asInterface(service);
            try {
//                注册书籍变化监听器
                bookManager.registListener(listener);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

//    书籍变化监听器实现
    private IOnBookChangeListener listener = new IOnBookChangeListener.Stub() {
        @Override
        public void onChangeBook(Book book) throws RemoteException {
            Log.e("tag" , "changeBook : " + book);
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_book);
//        绑定service
        Intent intent = new Intent(this , BookService.class);
        bindService(intent , connection , Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
//        解绑service
        unbindService(connection);
        super.onDestroy();
    }

//    获取书籍列表
    public void getBookList(View view) throws RemoteException {
        List books = bookManager.getBookList();
        Log.e("tag" , "books : " + books);
    }
//   添加书籍
    public void addBook(View view) throws RemoteException {
        Book book = new Book(bookId , "AndroidBook" + bookId);
        bookManager.addBook(book);
        bookId++;
    }
//  移除监听器
    public void removeListener(View view) {
        try {
            bookManager.removeListener(listener);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}

service代码:

这里有几点需要注意:

1.监听器,这里必须使用RemoteCallbackList,这是专门远程注册、移除监听器的类,如果使用常用的List,会发现无法移除监听器,大家可以试下,这里就不写出来的

2.循环监听器List时调用listeners.beginBroadcast(),并在使用结束后,调用listeners.finishBroadcast(),并且不可以直接写for (int i = 0;i

public class BookService extends Service {
//    监听器,这里必须使用RemoteCallbackList,这是专门远程注册、移除监听器的类,如果使用常用的List,会发现无法移除监听器,大家可以试下,这里就不写出来的
    private RemoteCallbackList listeners = new RemoteCallbackList<>();
//    模拟书籍
    private List books = new ArrayList<>();
//    实现我们定义的IBookManager
    private IBinder mBinder = new IBookManager.Stub(){

        @Override
        public List getBookList() throws RemoteException {
            return books;
        }

        @Override
        public void addBook(Book book)  {
            books.add(book);
            try {
//                获取listener数量,这里一定要写出来,不可以直接写for (int i = 0;i

这里只是使用!!!!!!!不介绍实现!!!

你可能感兴趣的:(Android,消息机制)