AIDL使用整理

AIDL 全稱:android interface defination language 安卓接口定義語言。適用於進程間通信。

首先創建Book對象

package com.example.test.aidl;

import android.os.Parcel;
import android.os.Parcelable;

import java.io.Serializable;

/**
 * Description:
 */

public class Book implements Parcelable{
    private int bookId;
    private String bookName;

    public Book(int bookId,String bookName){
        this.bookId = bookId;
        this.bookName = bookName;
    }

    protected Book(Parcel in) {
        bookId = in.readInt();
        bookName = in.readString();
    }

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

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

    public int getBookId() {
        return bookId ;
    }

    public void setBookId(int bookId) {
        this.bookId = bookId;
    }

    public String getBookName() {
        return bookName ;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

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

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

創建Book.aidl文件
在這裏插入圖片描述
修改Book.aidl內容

package com.example.test.aidl;

parcelable Book;

再創建IBookManager.aidl文件
提供兩個方法,addBook和getBookList方法

package com.example.test.aidl;
import com.example.test.aidl.Book;

interface IBookManager {
     List<Book> getBookList();
     void addBook(in Book book);
}

接下來就服務端,創建BookManagerService繼承Service,在onCreate()中初始化添加了4本書。並創建一個Binder對象在onBind()中返回。

package com.example.test.aidl;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Description:
 */

public class BookManagerService extends Service{
    private static final String TAG = "BookManagerService";


    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,"西遊記"));
        mBookList.add(new Book(2,"紅樓夢"));
        mBookList.add(new Book(3,"水滸傳"));
        mBookList.add(new Book(4,"三國演義"));
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

在AndroidManifest.xml中註冊

 	    <service
            android:name=".aidl.BookManagerService"
            android:process=":BookManagerService">
        </service>

創建AidlActivity,和BookManagerService建立連接。

package com.example.test.aidl;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import com.example.test.R;

import java.util.List;

public class AidlActivity extends AppCompatActivity {

    private static final String TAG = "AidlActivity";

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            IBookManager iBookManager = IBookManager.Stub.asInterface(service);
            try {
                List<Book> bookList = iBookManager.getBookList();
                for (int i = 0; i < bookList.size(); i++) {
                    Book book = bookList.get(i);
                    Log.e(TAG, "Book: bookName ————"+book.getBookName() +"|||  bookId ————" +book.getBookId());
                }
            } catch (RemoteException e) {

            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_aidl);

        Intent intent = new Intent(this,BookManagerService.class);
        bindService(intent,mServiceConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        unbindService(mServiceConnection);
        super.onDestroy();
    }
}

運行程序,查看控制檯數據。
在這裏插入圖片描述
在這裏只調用了getBookList()方法,嘗試調用一下addBook()方法。修改如下:

 private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            IBookManager iBookManager = IBookManager.Stub.asInterface(service);
            try {
                //添加一本書籍
                iBookManager.addBook(new Book(5,"三打白骨精"));
                
                List<Book> bookList = iBookManager.getBookList();
                
                for (int i = 0; i < bookList.size(); i++) {
                    Book book = bookList.get(i);
                    Log.e(TAG, "Book: bookName ————"+book.getBookName() +"|||  bookId ————" +book.getBookId());
                }
            } catch (RemoteException e) {

            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

重新運行,發現數據已經添加上去了。
在這裏插入圖片描述下面我們來模擬一下每當有新的圖書添加進來就通知用戶。首先需要提供一個AIDL接口,用戶可以開啓提醒和取消提醒。

首先創建IOnNewBookArrivedListener.aidl文件,並提供onNewBookArrived()方法

// IOnNewBookArrivedListener.aidl
package com.example.test.aidl;
import com.example.test.aidl.Book;
// Declare any non-default types here with import statements

interface IOnNewBookArrivedListener {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void onNewBookArrived(in Book book);
}

然後在原有的IBookManager.aidl中添加兩個新方法

package com.example.test.aidl;
import com.example.test.aidl.Book;

interface IBookManager {
     List<Book> getBookList();
     void addBook(in Book book);
     void registerListener(IOnNewBookArrivedListener listener);
     void unregisterListener(IOnNewBookArrivedListener listener);
}

BookManagerService中也需要修改下,並在OnCreate()中啓動了一個線程,每隔5秒添加一本新書到BookList中。

package com.example.test.aidl;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Description:
 */

public class BookManagerService extends Service{
    private static final String TAG = "BookManagerService";

    private AtomicBoolean mAtomicBoolean = new AtomicBoolean(false);

    private CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<>();
    private CopyOnWriteArrayList<IOnNewBookArrivedListener> mListenerList = 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 registerListener(IOnNewBookArrivedListener listener) throws RemoteException {
            if (!mListenerList.contains(listener)) {
                mListenerList.add(listener);
            }
            Log.e(TAG, "registerListener:   mListenerList大小"+mListenerList.size());
        }

        @Override
        public void unregisterListener(IOnNewBookArrivedListener listener) throws RemoteException {
            if (mListenerList.contains(listener)) {
                mListenerList.remove(listener);
            }
            Log.e(TAG, "registerListener:   mListenerList大小"+mListenerList.size());
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();

        mBookList.add(new Book(1,"西遊記"));
        mBookList.add(new Book(2,"紅樓夢"));
        mBookList.add(new Book(3,"水滸傳"));
        mBookList.add(new Book(4,"三國演義"));

        new Thread(new ServiceWorker()).start();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    private void onNewBookArrived(Book book) throws RemoteException {
        mBookList.add(book);

        for (int i = 0; i < mListenerList.size(); i++) {
            IOnNewBookArrivedListener iOnNewBookArrivedListener = mListenerList.get(i);
            iOnNewBookArrivedListener.onNewBookArrived(book);
        }
    }

    private class ServiceWorker implements Runnable{

        @Override
        public void run() {
            //爲真時一直執行
            while (!mAtomicBoolean.get()){

                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                int bookId = mBookList.size()+1;
                Book book = new Book(bookId,"火影忍者第"+bookId+"話");
                try {
                    onNewBookArrived(book);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void onDestroy() {
        mAtomicBoolean.set(true);
        super.onDestroy();
    }
}

然後AidlActivity中在連接BookManagerService時開啓提醒,即註冊,銷燬的時候取消提醒,即取消註冊。

package com.example.test.aidl;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import com.example.test.R;
import com.example.test.utils.Constants;

import java.util.List;

public class AidlActivity extends AppCompatActivity {

    private static final String TAG = "AidlActivity";
    private IBookManager mIBookManager;

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            IBookManager iBookManager = IBookManager.Stub.asInterface(service);
            try {
                mIBookManager = iBookManager;
                iBookManager.addBook(new Book(5,"三打白骨精"));

                List<Book> bookList = iBookManager.getBookList();

                for (int i = 0; i < bookList.size(); i++) {
                    Book book = bookList.get(i);
                    Log.e(TAG, "Book: bookName ————"+book.getBookName() +"|||  bookId ————" +book.getBookId());
                }
                //註冊
                iBookManager.registerListener(mIOnNewBookArrivedListener);
            } catch (RemoteException e) {

            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case Constants.BOOKARRIVED:
                   Book book = (Book) msg.obj;
                    Log.e(TAG, "Book: bookName ————"+book.getBookName() +"|||  bookId ————" +book.getBookId());
                    break;
                    default:
                        super.handleMessage(msg);

                        break;
            }
        }
    };

    private IOnNewBookArrivedListener mIOnNewBookArrivedListener = new IOnNewBookArrivedListener.Stub() {
        @Override
        public void onNewBookArrived(Book book) throws RemoteException {
            mHandler.obtainMessage(Constants.BOOKARRIVED,book).sendToTarget();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_aidl);

        Intent intent = new Intent(this,BookManagerService.class);
        bindService(intent,mServiceConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        if (mIBookManager != null && mIBookManager.asBinder().isBinderAlive()) {
            try {
                //取消註冊
                mIBookManager.unregisterListener(mIOnNewBookArrivedListener);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        unbindService(mServiceConnection);
        super.onDestroy();
    }
}

然後重新運行程序。可以看出來每隔5秒就會收到新書的消息。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章