Android学习之跨进程通信安卓接口定义语言AIDL(一)

今天来写下安卓接口定义语言,也就是大家听了都头疼的AIDL,今天有幸看到慕课网的AIDL视频学习了一下,在此感谢慕课网,是个很不错的网站。

进入正题,Android中跨进程是如何传递数据的?如果是Service方面的当然是AIDL。

Android中2个进程无法直接通信,必须通过Android系统底层间接通信,而跨进程通信有4种方式,分别对应4大组件,其中Service对应的就叫AIDL,即Android Interface Defined Language安卓接口定义语言

基本语法:

语法和Java接口类似

只支持方法,不能定义静态成员

运行方法有任何类型的参数和返回值

除默认类型外,均需要导包

AIDL使用情况:
IPC:Inter-Process Communication进程间通信
什么时候用AIDL?有IPC,多线程,多个应用程序
什么时候用Binder?只有IPC,无多线程,多个应用程序
什么时候用Messenger?只有IPC,无多线程
AIDL使用过程:
1.创建.aidl文件
sdk中的build-tools目录下提供了aidl工具,用来将aidl文件转换成java可编译文件
Eclipse:新建包,新建file,后缀为.aidl,按格式敲上代码,java文件在gen/相同包名之下自动会创建
Android Studio:右键new AIDL即可,java文件在build/generated/source/aidl/debug/相同包名之下自动会创建
2.实现接口
创建一个Service,重写onBind(),然后实例化IBinder iBinder = new IDemoAidlInterface.Stub() {}并实现其中的方法
3.向客户端暴露接口
继承Service并且重写onBind(),返回IBinder

4.客户端绑定服务,拿到远程的服务

下面讲下Demo:

先在app中新建AIDL,这个app作为服务端,右键工程new AIDL即可,java文件在build/generated/source/aidl/debug/相同包名之下自动会创建

package yuzhentao.aidldemo;

//interface:关键字,IDemoAidlInterface:接口名
interface IDemoAidlInterface {

    //add():方法
    int add(int num1, int num2);

}

创建一个Service,实例化IBinder iBinder = new IDemoAidlInterface.Stub() {}并实现其中的方法也就是add(),还要重写onBInd(),返回值就是iBinder

/**
 * Aidl服务
 *
 * @author yuzhentao
 */
public class IDemoAidlService extends Service {

    /**
     * 当客服端绑定到服务端时会执行
     *
     * @param intent:Intent
     * @return IBinder
     */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return iBinder;
    }

    private IBinder iBinder = new IDemoAidlInterface.Stub() {
        @Override
        public int add(int num1, int num2) throws RemoteException {
            Log.e("yzt", "收到远程请求,输入的参数是:" + num1 + "和" + num2);
            return num1 + num2;
        }
    };

}

不要忘记在AndroidManifest.xml中注册这个Service,android:enabled和android:exported必须为true,android:exported用于指示该服务是否能够被其他应用程序组件调用或跟它交互。如果设置为true,则能够被调用或交互,否则不能。也就是能被跨进程使用。

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

接下来使用Android Studio的File来new一个module,这个module作为客户端,很重要的一步就是复制.aidl文件,.aidl必须和服务端的一样,包括包名,否则编译不通过,然后写客户端的布局,这里要实现一个加法的功能

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <EditText
        android:id="@+id/edittext_num1_activity_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="+"
        android:textSize="20dp" />

    <EditText
        android:id="@+id/edittext_num2_activity_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="="
        android:textSize="20dp" />

    <EditText
        android:id="@+id/edittext_result_activity_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:editable="false" />

    <Button
        android:id="@+id/button_activity_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="发送远程请求"
        android:textSize="16dp" />

</LinearLayout>
然后客户端主界面中来获取客户端,先要绑定服务,Intent必须是显式的,参数为包名和类名的全称,然后实现ServiceConnection接口,onServiceConnected()中通过
IDemoAidlInterface.Stub.asInterface(service)

返回IDemoAidlInterface,拿到远程的服务,这个IDemoAidlInterface就是AIDL的java文件,最后是单击事件中通过IDemoAidlInterface来调用add()方法把数据传递到服务端,计算就是在服务端中进行的,以下是完整代码:

/**
 * 客户端
 * 获取服务端
 * .aidl必须和服务端的一样,包括包名,负责编译不通过
 *
 * @author yuzhentao
 */
public class MainActivity extends Activity {

    private IDemoAidlInterface iDemoAidlInterface;
    /**
     * 服务连接接口
     */
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {//连接服务时执行,ComponentName是bindService()指定的,IBinder是服务端的onBind()返回的
            iDemoAidlInterface = IDemoAidlInterface.Stub.asInterface(service);//返回IDemoAidlInterface,拿到了远程的服务的代理
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {//断开服务时执行
            iDemoAidlInterface = null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        bindService();//绑定服务
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(conn);//解绑服务
    }

    private void initView() {
        final EditText etNum1 = (EditText) findViewById(R.id.edittext_num1_activity_main);
        final EditText etNum2 = (EditText) findViewById(R.id.edittext_num2_activity_main);
        final EditText etResult = (EditText) findViewById(R.id.edittext_result_activity_main);
        findViewById(R.id.button_activity_main).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int num1 = Integer.parseInt(etNum1.getText().toString());
                int num2 = Integer.parseInt(etNum2.getText().toString());
                String result;
                try {
                    result = iDemoAidlInterface.add(num1, num2) + "";//调用远程的服务
                    etResult.setText(result);
                } catch (RemoteException e) {
                    e.printStackTrace();
                    etResult.setText("发生错误");
                }
            }
        });
    }

    /**
     * 绑定服务
     * alt+command+m:提取方法
     */
    private void bindService() {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("yuzhentao.aidldemo", "yuzhentao.aidldemo.IDemoAidlService"));//显式Intent
        bindService(intent, conn, Context.BIND_AUTO_CREATE);//绑定服务
    }

}
最后是效果图,左边是服务端,右边客户端输入2个值,点击发送远程请求,服务端就会返回值到客户端,这是在2个进程间实现的,希望对大家有点帮助:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值