学习AIDL入门-一个简单的小demo

目录

1、简介

2、AIDL实战

2.1 创建一个Project

2.2 创建服务端

2.3 创建一个客户端应用

2.4 测试

3、其他思考

3.1 如果有多个client 绑定同一个Service,那么是一个client对应一个service还是多个client对应同一个service?

3.2 Service的生命周期是怎样的?

3.3 client最好都是异步来调用aidl接口

3.4 通过aidl如何对一个自定义对象进行传输?

参考文献


1、简介

Android中跨进程数据传输方式有很多种,例如四大组件之一的ContentProvider、bundle及AIDL等等,本篇文章主要采用一个Demo的方式来讲述AIDL的基本用法。

什么是AIDL?

引用官方翻译的一句话:AIDL(Android 接口定义语言),您可以利用它定义客户端与服务使用进程间通信 (IPC) 进行相互通信时都认可的编程接口。再此之前,你如果没有了解过AIDL,很难理解这句话的真正含义,这也是本文为何从实现一个Demo入手来真正理解AIDL的原因。

2、AIDL实战

2.1 创建一个Project

使用Android Studio 创建一个Project,这一步十分简单,这里就不截图展示了。

2.2 创建服务端

在通过Android Studio创建一个Project的时候,默认会为我们创建一个app应用,在此我们就以app作为服务端。

2.2.1 创建aidl文件

首先使用Android Studio 创建一个AIDL Folder,例如下图:

注意选择的是为application的module,此时会在main目录下看到一个aidl文件夹。然后再该文件夹下创建一个aidl文件,具体如下图:

命名好文件名,我们会看到在aidl文件夹下会创建与应用程序相同的包,在包下会有对应的aidl文件,如下:

以上几步,可能不同版本的Android Studio创建aidl的位置不一样,但是最终都需要把aidl文件夹及文件都移至main文件夹下,并且aidl文件的包名必须和应用程序的包名一致。

编译一下整个项目,我们就能够在build文件夹下看到具体的.java文件,如下:

此文件是自动生成的,我们可以不用去理会。

2.2.2 为aidl文件添加代码

打开aidl文件,我们发现它其实就是一个接口,我们可以添加我们需要的方法,例如我添加如下:

2.2.3 创建一个Service

如果需要使用AIDL,它需要绑定在一个服务之上,因此需要创建一个Service来实现aidl中的具体接口。我实现的代码如下:

此时我们的服务端已经编写完成,接下来可以进行客户端的实现了。

2.3 创建一个客户端应用

2.3.1 创建一个moudle并拷贝aidl文件

在2.1中的project下,我们右键再次创建一个类型为application的module,同时将app中我们创建好的aidl文件拷贝到相同的目录下。例如下:

2.3.2 activity中绑定具体的服务

有关activity中的布局文件,此处就不在粘贴,这里将activity中的代码全部粘贴如下:

public class AidlClientTestMainActivity extends AppCompatActivity {

    private EditText mEtData1;
    private EditText mEtData2;
    private TextView mTvShowResult;

    private IMyAidlInterface iMyAidlInterface;

    private ServiceConnection conn = new ServiceConnection() {

        // 绑定上服务
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            Log.i("lvjie", "onServiceConnected()...");
            iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
        }

        // 断开服务
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.i("lvjie", "onServiceDisconnected()...");
            iMyAidlInterface = null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_aidl_client_test_main);

        initView();
    }

    private void initView(){
        this.mEtData1 = (EditText) findViewById(R.id.et_data_1);
        this.mEtData2 = (EditText) findViewById(R.id.et_data_2);
        this.mTvShowResult = (TextView) findViewById(R.id.tv_show_result);
    }

    // Button绑定了此函数
    public void onClickConnectService(View view){
        bindAidlService();
    }

    // Button绑定了此函数
    public void onClickAidlTestBtn(View view){

        int num1 = 0;
        int num2 = 0;
        try {
            num1 = Integer.parseInt(this.mEtData1.getText().toString());
            num2 = Integer.parseInt(this.mEtData2.getText().toString());
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }

        try {
            int result = iMyAidlInterface.add(num1, num2);

            mTvShowResult.setText(""+num1+" + "+num2+" = "+result);
        } catch (RemoteException e) {
            Log.i("lvjie", e.toString());
            mTvShowResult.setText("出错了...");
        }
    }

    private void bindAidlService() {
        // 获取服务
        Intent intent = new Intent();
        // 显示intent启动服务, 需要注意此处的包名和MyAidlService类的全名
        intent.setComponent(new ComponentName("com.android.study.example", "com.android.study.example.aidl.MyAidlService"));

        bindService(intent, conn, Context.BIND_AUTO_CREATE);
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(conn);
    }
}

2.4 测试

首先我们需要运行app,将此应用程序安装到手机或模拟器上,再次运行myaidlclient应用程序,最后演示myaidlclient应用程序如下:

3、其他思考

3.1 如果有多个client 绑定同一个Service,那么是一个client对应一个service还是多个client对应同一个service?

答案是多个client对应同一个Service,通常情况下我们都会让这个Service运行再一个单独的进程中。

3.2 Service的生命周期是怎样的?

当第一个client绑定Service后,会启动该Service,即执行对应的构造函数、onCreate、onBind等函数,其他的client再绑定该service的时候是不会再次执行构造等函数的。当有的client都解绑后,直到最后一个client解绑是,Service才会执行onUnbind、onDestroy等函数。

3.3 client最好都是异步来调用aidl接口

虽然是跨进程调用,但是默认情况下client调用aidl时都是同步调用的,由于Android中不建议在主线程中做耗时操作,通常情况我们是无法预知aidl提供的接口是否耗时,因此建议调用aidl接口时都在一个子线程中完成。

3.4 通过aidl如何对一个自定义对象进行传输?

参考链接:学习AIDL入门-传递自定义类的对象

最后,我们再来看看官方的译文:AIDL(Android 接口定义语言),您可以利用它定义客户端与服务使用进程间通信 (IPC) 进行相互通信时都认可的编程接口。是不是容易理解多了,在client和service端,都存在一份aidl文件,该文件就是两者通信都认可的编程接口。

 

参考文献

https://developer.android.com/guide/components/aidl

发布了74 篇原创文章 · 获赞 17 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/u010349644/article/details/86583816