Android AIDL不同应用通信

简介

AIDL(Android接口定义语言),用于定义客户端与服务端进程间IPC通信接口。在Android,不同进程无法共享内存,所以使用AIDL通信

服务端使用AIDL的流程

1、在AIDL文件中定义接口IRemoteInterface(方法与变量)

2、Rebuild项目生成IBinder接口IRemoteInterface.Stub

3、实现IBinder接口内部的Stub抽象类(方法的具体实现),可以在Service中匿名实现

4、实现RemoteService重写onBind()来向客户端公开接口(return binder)

可以再Service中重写匿名内部类binder实例。然后再onbind中return

客户端使用AIDL流程

客户端需要包含AIDL文件,才能拥有接口类访问权限(IRemoteInterface)

在Activity中调用bindService连接服务。binderService需要intent(service),connection。

intent

        Intent intent = new Intent();
        intent.setAction("com.example.settinglib.fruitservice");
        intent.setPackage("com.example.administrator.testdemo");//设置服务端的package
        bindService(intent, mConnection, BIND_AUTO_CREATE);

connection

 private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //连接后拿到 Binder,转换成 AIDL,在不同进程会返回个代理
            mAidl = IFruitManger.Stub.asInterface(service);
        }
 
        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

之后就可以用该接口调用服务端的方法

高级技巧

服务端创建各种实体类,实体类需要实现Parcelable接口。只有可序列化的数据才可以在不同进程间传送

public class Fruit implements Parcelable {
    private String mName ;
    private int mNumber;
 
    public Fruit(Parcel source) {
        mName = source.readString();
        mNumber = source.readInt();
    }
 
    public String getmName() {
        return mName;
    }
 
    public void setmName(String mName) {
        this.mName = mName;
    }
 
    public int getmNumber() {
        return mNumber;
    }
 
    public void setmNumber(int mNumber) {
        this.mNumber = mNumber;
    }
 
    public Fruit(String name, int number) {
        this.mName = name;
        this.mNumber = number;
    }
 
    public static final Creator<Fruit> CREATOR = new Creator<Fruit>() {
        @Override
        public Fruit createFromParcel(Parcel in) {
            return new Fruit(in);
        }
 
        @Override
        public Fruit[] newArray(int size) {
            return new Fruit[size];
        }
    };
 
    @Override
    public int describeContents() {
        return 0;
    }
 
    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(mName);
        parcel.writeInt(mNumber);
    }
 
 
    @Override
    public String toString() {
        return String.format("[mName:%s, mNumber:%s]", mName, mNumber);
    }
}

创建AIDL文件Fruit.aidl

package com.example.settinglib;
parcelable Fruit;

创建IFruitManager.aidl

aidl中,除了基本数据类型,其他数据类型必须用  in/out/inout  其中一种标识

in:输入型参数

out:输出型参数

intout:输入输出型参数

package com.example.settinglib;
import com.example.settinglib.Fruit;
import com.example.settinglib.INewFruitAddListener;
interface IFruitManger {
    void addFruit(in Fruit fruit);
    List<Fruit> getFruitList();
    void registerListener(INewFruitAddListener listener);
    void unregisterListener(INewFruitAddListener listener);
}

创建服务监听器INewFruitAddListener

package com.example.settinglib;
import com.example.settinglib.Fruit;
interface INewFruitAddListener {
    void onINewFruitAdd(in Fruit fruit);
}

创建服务FruitService

public class FruitService extends Service {
    private ArrayList<Fruit> mFruits;
    //它是线程安全的
    private AtomicBoolean mIsServiceDestory = new AtomicBoolean(false);
    private RemoteCallbackList<INewFruitAddListener> mListenerList = new RemoteCallbackList<INewFruitAddListener>();
 
    @Override
    public IBinder onBind(Intent intent) {
        //检测权限,客服端没有注册这个权限,就不让绑定服务
        int check = checkCallingOrSelfPermission("com.example.settinglib.permission.ACCESS_FRUIT_SERVICE");
        if (check == PackageManager.PERMISSION_DENIED){
            Log.e("date", "PERMISSION_DENIED: ACCESS_FRUIT_SERVICE" );
            return null;
        }
        mFruits = new ArrayList<Fruit>();
        mFruits.add(new Fruit("apple", 2));
        mFruits.add(new Fruit("banana", 4));
        return mIBinder;
    }
 
    /**
     * 创建生成的本地 Binder 对象,实现 AIDL 制定的方法
     */
    private IBinder mIBinder = new IFruitManger.Stub() {
        @Override
        public void addFruit(Fruit fruit) throws RemoteException {
            mFruits.add(fruit);
        }
 
        @Override
        public List<Fruit> getFruitList() throws RemoteException {
            return mFruits;
        }
 
        @Override
        public void registerListener(INewFruitAddListener listener) throws RemoteException {
            mListenerList.register(listener);
        }
 
        @Override
        public void unregisterListener(INewFruitAddListener listener) throws RemoteException {
            mListenerList.unregister(listener);
        }
    };
 
    private void onINewFruitAdd(Fruit fruit) throws RemoteException {
        mFruits.add(fruit);
        int number = mListenerList.beginBroadcast();
        for (int i = 0; i < number; i++) {
            INewFruitAddListener listener = mListenerList.getBroadcastItem(i);
            if (listener != null) {
                try {
                    listener.onINewFruitAdd(fruit);
                } catch (RemoteException e) {
                    Log.e("date", "onINewFruitAdd: " + e.getMessage());
                }
            }
        }
        mListenerList.finishBroadcast();
    }
 
    @Override
    public void onCreate() {
        super.onCreate();
        new Thread(new ServiceWork()).start();
    }
 
    @Override
    public void onDestroy() {
        super.onDestroy();
        mIsServiceDestory.set(true);
    }
 
    /**
     *模拟,每隔3s 向客服端添加一条数据
     * */
    private class ServiceWork implements Runnable {
        @Override
        public void run() {
            while (!mIsServiceDestory.get()) {
                try {
                    Thread.sleep(3000);
                    int fruitId = mFruits.size() + 1;
                    onINewFruitAdd(new Fruit("茄子", fruitId));
                } catch (Exception e) {
                    Log.e("date", "ServiceWork: " + e.getMessage());
                }
            }
        }
    }
}

注册服务

      <service
            android:name=".FruitService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.settinglib.fruitservice"/>
            </intent-filter>
        </service>

客户端连接服务

 private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //连接后拿到 Binder,转换成 AIDL,在不同进程会返回个代理
            mAidl = IFruitManger.Stub.asInterface(service);
          
            try {
                if (mAidl != null) 
                    mAidl.registerListener(mFruitListener);
                
            } catch (RemoteException e) {
                Log.e(TAG, "onCreate: " + e.getMessage());
            }
        }
 
        @Override
        public void onServiceDisconnected(ComponentName name) {
 
            try {
                //mAidl为服务端进行的Service对象,通过asBinder()可以获得Binder对象
                mAidl.asBinder().linkToDeath(mDeathRecipient, 0);
            } catch (RemoteException e) {
                Log.e(TAG, "onServiceDisconnected: " + e);
            }
        }
    };
 
 
   private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
        @Override
        public void binderDied() {
            if (mAidl == null) return;
            //解除死亡通知,如果Binder死亡了,不会在触发binderDied方法
            mAidl.asBinder().unlinkToDeath(mDeathRecipient, 0);
            mAidl = null;
            //重新绑定服务
            Intent intent = new Intent();
            intent.setAction("com.example.settinglib.fruitservice");
            intent.setPackage("com.example.administrator.testdemo");//设置服务端的package
            bindService(intent, mConnection, BIND_AUTO_CREATE);
        }
    };

客户端监听数据

    private INewFruitAddListener mFruitListener = new INewFruitAddListener.Stub() {
        @Override
        public void onINewFruitAdd(Fruit fruit) throws RemoteException {
            Log.e(TAG, "onINewFruitAdd: ");
            weakHandler.obtainMessage(FRUIT_ADD,fruit).sendToTarget();
        }
    };
 
 
    private HandlerUtil.WeakHandler weakHandler = new HandlerUtil.WeakHandler(this);
        @Override
        public void handleMessage(Message message) {
            switch (message.what) {
                case FRUIT_ADD:
                    Fruit fruit = (Fruit) message.obj;
                    Log.e("date", "添加新的水果了: " + fruit.getmName() + fruit.getmNumber());
                    ToastUtils.showShortToast("添加新的水果了: " + fruit.getmName() + fruit.getmNumber());
                    break;
        }
    }

各种操作

 private ExecutorService mSingleThread= Executors.newSingleThreadExecutor();
 
 private void queryData() {
        if (!mSingleThread.isShutdown()){
            mSingleThread.execute(new Runnable() {
                @Override
                public void run() {
                    List<Fruit> fruitList = null;
                    try {
                        fruitList = mAidl.getFruitList();
                        ToastUtils.showShortToast("水果的数量: " + fruitList.size());
                        for (int i = 0; i < fruitList.size(); i++) {
                            Log.e("date", fruitList.get(i).getmName());
                        }
                    } catch (RemoteException e) {
                    }
                }
            });
        }
    }

 

posted @ 2022-10-09 17:21  Miraculous_B  阅读(187)  评论(0编辑  收藏  举报