AS开发AIDL程序(2)

本文介绍如何使用 Android 的 AIDL (Android Interface Definition Language) 实现跨进程通信,包括创建 AIDL 文件、定义接口及其实现,以及在 Activity 和 Service 中的绑定和服务交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上文中介绍了对象的序列化和Binder的使用,这篇文章主要介绍AndroidStudio开发AIDL的过程,如果没有看过上一篇的可以移步Anddroid中Binder的用法和对象的序列化
实现的功能大致是在主进程的Activity中调用其他进程中的方法。
Android的SDK会帮助我们自动生成Binder类。
第一步:创建图书管理的接口aidl文件,右键创建斯大林文件
选择创建AIDL FILE,这里我们选择穿件一个接口IBookManager
这接口里封装了两个方法代码如下:

// IBookManager.aidl
package com.lizhi.demo.ipc.aidl;

// Declare any non-default types here with import statements
import com.lizhi.demo.ipc.aidl.Book;
import com.lizhi.demo.ipc.aidl.IOnNewBookArrivedListener;

interface IBookManager {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

    void addBook(in Book book);
    List<Book> getBookList();


}

这时候AndroidStudio会默认为我们创建一个包
如图所示上面的aidl包就是AndroidStudio默认给我创建的和我们自己建立的包是完全一样的。接口里有两个方法addBookgetBookList
注意addBook的方法参数有个in这是aidl文件特有的表示输入行参数,除了in还有out ,ountin
第二步:创建实体类Book实现Percalable接口代码:

package com.lizhi.demo.ipc.aidl;

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

/**
 * Created by Administrator on 2015/12/30.
 */
public class Book implements Parcelable {

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

    public String bookName;
    public String bookId;


    protected Book(Parcel in) {
        bookName = in.readString();
        bookId = 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];
        }
    };

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

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


    @Override
    public String toString() {
        return "Book{" +
                "bookName='" + bookName + '\'' +
                ", bookId='" + bookId + '\'' +
                '}';
    }
}

注意这个是个java类创建在我们自己的包中(不是AndroidStudio给我生成的那个包)然后创建这个Book对应的aidl文件(在系统帮我们生成的包中创建),为什么要创建呢?因为在aidl中不能引用java类所以我们要自己创建一个。Book.aidl文件如下:

package com.lizhi.demo.ipc.aidl;
parcelable Book;

很简单 就指定这个类是Parcelable类型的就行了。
你有可能注意到在IBookManager.aidl中我们
import com.lizhi.demo.ipc.aidl.Book;
即使他俩在同一个包中,这就是aidl特有的。
实现上面两步后我们就开始下Activity和Sercice了
在Activity中很简单 只需要绑定Service就好了

     Intent aidlIntent = new Intent();
                aidlIntent.setClass(this, AidlSercice.class);
                boolean aidlBind = bindService(aidlIntent, aidlConnection, Context.BIND_AUTO_CREATE);
                LogUtil.log("-------aidlBind------->" + aidlBind);

    ServiceConnection aidlConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iBookManager = IBookManager.Stub.asInterface(service);
            List<Book> bookList = null;
            try {
                bookList = iBookManager.getBookList();
                LogUtil.log("---------aidl----->" + bookList.getClass().getCanonicalName());
                LogUtil.log("-------aidl--toString----->" + bookList.toString());
                iBookManager.registerListener(onNewBookArrivedListener);
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            LogUtil.log("-------aidl--onServiceDisconnected----->");

        }
    };

ServiceConnectiononServiceConnected中我们拿到IBookManager通过这个接口就可进行添加和获取列表的方法了
接下来我们在看看Service中的实现:

package com.lizhi.demo.ipc;

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

import com.lizhi.demo.ipc.aidl.Book;
import com.lizhi.demo.ipc.aidl.IBookManager;
import com.lizhi.demo.ipc.aidl.IOnNewBookArrivedListener;
import com.lizhi.demo.utils.LogUtil;

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

/**
 * Created by Administrator on 2015/12/30.
 */
public class AidlSercice extends Service {

    //线程安全的List
    CopyOnWriteArrayList<Book> mList = new CopyOnWriteArrayList<>();
    //    CopyOnWriteArrayList<IOnNewBookArrivedListener> listeners = new CopyOnWriteArrayList<>();
    RemoteCallbackList<IOnNewBookArrivedListener> listeners = new RemoteCallbackList<>();
    int count;

    @Override
    public void onCreate() {
        super.onCreate();
        mList.add(new Book("葵花宝典", "1"));
        mList.add(new Book("皮鞋简朴", "2"));
        LogUtil.log("--------onCreate-----");

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(2000);
                        onNewBoolAdd(new Book("" + count, "" + count));
                        count++;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }


    Binder mBinder = new IBookManager.Stub() {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        @Override
        public void addBook(Book book) throws RemoteException {
            LogUtil.log("---------addBook-------addBook------" + book);
            mList.add(book);
        }

        @Override
        public List<Book> getBookList() throws RemoteException {
            LogUtil.log("---------AidlSercice-------getBookList------" + mList);
            return mList;
        }

        @Override
        public void registerListener(IOnNewBookArrivedListener listener) throws RemoteException {
            listeners.register(listener);
        }

        @Override
        public void unregisterListener(IOnNewBookArrivedListener listener) throws RemoteException {
            listeners.unregister(listener);
        }
    };


    public void onNewBoolAdd(Book book) {
        final int N = listeners.beginBroadcast();
        for (int i = 0; i < N; i++) {
            IOnNewBookArrivedListener l = listeners.getBroadcastItem(i);
            if (l != null) {
                try {
                    l.onNetBookArrived(book);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
        listeners.finishBroadcast();
        mList.add(book);
    }

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

在Service的onBind方法中我们返回IBookManager.Stub对象,这个对象就是一个Binder对象可以进行夸进程的通信。至于Stub这个对象是IbookManager接口的内部类,系统帮我们生成一个,在Activity中的onServiceConnected中我们调用了iBookManager = IBookManager.Stub.asInterface(service);这个方法生成Service里的接口对象。asInterface这个方法会进行判断如果是夸进程则生成一个夸进程的代理可以进行进程间的通信如果不是夸进程则返回对象本身。
这里只是实现简单的通信功能,其实进程间通信还有许多需要考虑的东西。大家可以慢慢挖掘。
最后说说注意事项:
ServiceConnextion中的

@Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iBookManager = IBookManager.Stub.asInterface(service);
            List<Book> bookList = null;
            try {
                bookList = iBookManager.getBookList();
                LogUtil.log("---------aidl----->" + bookList.getClass().getCanonicalName());
                LogUtil.log("-------aidl--toString----->" + bookList.toString());
                iBookManager.registerListener(onNewBookArrivedListener);
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }

方法中我调用了其他进程的方法,这里的onServiceConnected是运行在UI线程的如果其他进程的方法是个耗时的操作则不能这样写了 需要开启线程
Service里的方法是运行在Binder线程里的所以这些方法是可以运行耗时操作的不需要在开启线程了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值