android进阶-AIDL的基本使用

系列文章

AIDL的基本使用
AIDL之自定义数据类型
AIDL之重连方法
AIDL之接口注册/解注册
AIDL之连接池

知识点

  1. AIDL的基本概念
  2. AIDL的基本使用案例

一、AIDL的基本概念

AIDL定义:个人理解就是Android开发中提供的一种快速实现binder的工具,而binder就是一种跨进程通信,也可以不用AIDL,自己实现binder来达到同样的效果
AIDL支持的基本类型 : String,int,long,boolean,float,double,ArrayList,HashMap,Parcelable

二、AIDL的基本使用案例

本篇文章只实现最简单的两个进程通信,步骤如下:

  1. 先定义一个IPersion.aidl接口

 

interface IPerson {
    void  setName(String s);
    String  getName();
}
  1. 同步一下代码让IDE自动生成代码,生成后的代码路径为

 

build/generated/source/aidl/debug/包名/IPerson
  1. 编译服务端AIDLService,实例化binder对象并返回给客户端

 

public class AIDLService extends Service {

    private String name;

    private Binder binder=new IPerson.Stub() {
        @Override
        public void setName(String s) throws RemoteException {
            name=s;
        }

        @Override
        public String getName() throws RemoteException {
            return name;
        }
    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        LogUtil.d("onBind");
        return binder;
    }
}
  1. 客户端通过binderService获取binder后,就可以提供调用相应的方法

 

public class AIDLClientAcitvity extends Activity {


    @BindView(R.id.btn_bindservice)
    Button btnBindservice;
    @BindView(R.id.btn_setname)
    Button btnSetname;
    @BindView(R.id.btn_getName)
    Button btnGetName;
    @BindView(R.id.et_name)
    EditText etName;


    private IPerson iPerson;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_aidl_client);
        ButterKnife.bind(this);


    }

    @OnClick({R.id.btn_bindservice, R.id.btn_setname, R.id.btn_getName})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.btn_bindservice:
                bindServiceByAidl();
                break;
            case R.id.btn_setname:
                setName();
                break;
            case R.id.btn_getName:
                getName();
                break;
        }
    }


    private void bindServiceByAidl() {
        Intent intent = new Intent(this, AIDLService.class);
        bindService(intent, new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                LogUtil.d("onServiceConnected");
                iPerson = IPerson.Stub.asInterface(service);
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                LogUtil.d("onServiceDisconnected");
            }
        }, BIND_AUTO_CREATE);
    }


    private void setName() {
        if (iPerson != null) {
            try {
                iPerson.setName(etName.getText().toString().trim());
            } catch (RemoteException e) {
                e.printStackTrace();
                Toast.makeText(this, "setName error="+e, Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void getName(){
        if(iPerson!=null){
            try {
                Toast.makeText(this, iPerson.getName(), Toast.LENGTH_SHORT).show();iPerson.getName();
            } catch (RemoteException e) {
                e.printStackTrace();
                Toast.makeText(this, "getName error="+e, Toast.LENGTH_SHORT).show();
            }
        }
    }

}

(ps:可能有人会觉得这只是Activity与Service的通信,但是这个Service是可以换成其他应用的Service,当一个应用于另一个应用的服务通信的时候,就是跨进程通信的一种表现了,不过需要注意的是,服务端和客户端的AIDL包名路径要一致)


总结

本篇提供了一个最简单的aidl的使用方式,其实就是我们常用的bindService方式,但是从另一个概念上去理解这样的过程,会发现bindService所做事情的意义是很不一样的。
大家也可以去看下AIDL生成后的代码,尝试去理解下Stub.asInterfaceStub()的作用,你会发现不一样的东西
(ps:系列文章后续会更新完整)

Demo地址

https://github.com/returntolife455/DemoList


链接:https://www.jianshu.com/p/5043a1a69269
 

你可能感兴趣的:(android,android)