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
 

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