【android学习】AIDL跨进程通信

 

简介

AIDL 意思即 Android Interface Definition Language,翻译过来就是Android接口定义语言,是用于跨进程之间通信

AIDL支持的数据类型分为如下几种:

  • 八种基本数据类型:byte、char、short、int、long、float、double、boolean
  • String,CharSequence
  • 实现了Parcelable接口,Serializable接口的数据类型
  • List 类型。List承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象
  • Map类型。Map承载的数据必须是AIDL支持的类型,或者是其它声明的AIDL对象

项目简介

  1. aidl_server提供两个数字的假发
  2. aidl_client调用aidl_server提供的方法,计算两个数字的和

AIDL创建方式

注意:

  1. 服务器端的AIDL文件包需要和客户端的包名一致
  2. 在aidl文件中,如果需要应用其他的aidl文件,需要手动import(好似我的android studio不会自动导入)

项目创建

  • 服务端

服务端目录

 

Number.aidl

package com.zkq.aidl_server;

// Declare any non-default types here with import statements

parcelable Number;

Number.aidl文件中的parcelable是指引到同包名下的Number文件

Number需要继承Parcelable 实现序列化

public class Number implements Parcelable  {
    int num;

    public Number(int num) {
        this.num = num;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }


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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(this.num);
    }

    public Number() {
    }

    protected Number(Parcel in) {
        this.num = in.readInt();
    }

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

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

NumberManager.aidl实现了三个接口

  1. add 两个数字相加
  2. registerOnCountListener 注册相加后的结果监听器
  3. unregisterOnCountListener取消注册结果监听器

这里需要注意import了两个其他aidl文件(我的android studio不会自动引包,也不报错,但是编译时候会出错 Process 'command 'D:\android_sdk\build-tools\28.0.3\aidl.exe'' finished with non-zero exit value 1),所以需要手动添加

import com.zkq.aidl_server.Number;
import com.zkq.aidl_server.OnCountListener;

interface NumberManager {
    void add( in Number num1,in Number num2);
    void registerOnCountListener(in OnCountListener listener);
    void unregisterOnCountListener(in OnCountListener listener);
}

OnCountListener.aidl 实现了计算结果接口

import com.zkq.aidl_server.Number;

interface OnCountListener {
    void result(in Number result);
}

MyService文件

public class MyService extends Service {

    private RemoteCallbackList<OnCountListener> remoteCallbackList;

    NumberManager.Stub stub = new NumberManager.Stub() {
        @Override
        public void add(Number num1, Number num2) {

            int n1 = num1.getNum();
            int n2 = num2.getNum();

            Number result = new Number(n1+n2);

            int count = remoteCallbackList.beginBroadcast();
            for (int i = 0; i < count; i++) {
                OnCountListener broadcastItem = remoteCallbackList.getBroadcastItem(i);
                if (null!=broadcastItem){
                    try {
                        broadcastItem.result(result);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }
            remoteCallbackList.finishBroadcast();

        }

        @Override
        public void registerOnCountListener(OnCountListener listener) {
            remoteCallbackList.register(listener);
        }

        @Override
        public void unregisterOnCountListener(OnCountListener listener) {
            remoteCallbackList.unregister(listener);
        }
    };


    public MyService() {
        remoteCallbackList = new RemoteCallbackList<>();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return stub.asBinder();
    }
}

需要在AndroidManifest.xml中注册

    <service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"></service>

服务端就完成了

  • 客户端

注意

  1. NumberManager.aidl ,Number.aidl ,OnCountListener.aidl的包名需要和服务端一直,可以直接拷贝过来
  2. Number.class文件包名也需要和服务器一直,可以直接拷贝过来

 

我们这里只要就是在mainActivity里面,提取了几个重要的方法

绑定MyService

   private void bindServer() {
        Intent intent = new Intent();
        intent.setClassName("com.zkq.aidl_server", "com.zkq.aidl_server.MyService");
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
    }

 获得NumberManager


    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            NumberManager  manager = NumberManager.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            manager = null;
        }
    };

 相加的结果监听器

    private OnCountListener.Stub myOnCountListener = new OnCountListener.Stub() {
        @Override
        public void result(final Number result) throws RemoteException {

            Log.d("zkq", "-----> " + result.getNum());
        }
    };

 注册监听器

 manager.registerOnCountListener(myOnCountListener);

 取消注册监听器

manager.unregisterOnCountListener(myOnCountListener);

 两个方法相加

manager.add(number1, number2);

完整代码如下

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button mRegisterBtn;
    private Button mUnregisterBtn;
    private EditText mNum1Et;
    private EditText mNum2Et;
    private Button mAddBtn;
    private EditText mResultEt;


    NumberManager manager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        bindServer();
    }


    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            manager = NumberManager.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            manager = null;
        }
    };


    private OnCountListener.Stub myOnCountListener = new OnCountListener.Stub() {
        @Override
        public void result(final Number result) throws RemoteException {

            Log.d("zkq", "-----> " + result.getNum());
            mResultEt.post(new Runnable() {
                @Override
                public void run() {
                    mResultEt.setText(""+result.getNum());
                }
            });
        }
    };

    private void bindServer() {
        Intent intent = new Intent();
        intent.setClassName("com.zkq.aidl_server", "com.zkq.aidl_server.MyService");
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
    }

    private void initView() {
        mRegisterBtn = (Button) findViewById(R.id.btn_register);
        mRegisterBtn.setOnClickListener(this);
        mUnregisterBtn = (Button) findViewById(R.id.btn_unregister);
        mUnregisterBtn.setOnClickListener(this);
        mNum1Et = (EditText) findViewById(R.id.et_num1);
        mNum2Et = (EditText) findViewById(R.id.et_num2);
        mAddBtn = (Button) findViewById(R.id.btn_add);
        mAddBtn.setOnClickListener(this);
        mResultEt = (EditText) findViewById(R.id.et_result);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_register:
                // TODO 19/08/07
                try {
                    manager.registerOnCountListener(myOnCountListener);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.btn_unregister:
                // TODO 19/08/07
                try {
                    manager.unregisterOnCountListener(myOnCountListener);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.btn_add:
                // TODO 19/08/07

                if (TextUtils.isEmpty(mNum1Et.getText()) || TextUtils.isEmpty(mNum2Et.getText())) {
                    return;
                }
                int param1 = Integer.valueOf(mNum1Et.getText().toString());
                int param2 = Integer.valueOf(mNum2Et.getText().toString());
                Number number1 = new Number(param1);
                Number number2 = new Number(param2);
                try {
                    manager.add(number1, number2);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
            default:
                break;
        }
    }
}

demo下载  demo下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值