IPC(四)_Aidl的基本使用过程

AIDL全称 Android Interface definition language的缩写,顾名思义,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口.
下面是AIDL的详细使用过程。
简单起见,就完成一个客户端调用服务端,完成一次两个数加法的运算。
首先新建一个工程Server,然后规范起见,创建一个单独的.aidl的包。右键新建文件,创建一个.aidl的文件。

package com.example.server.aidl;
interface IAdd
{
int  add(int i,int j);
}

这个时候在工程根目录下会自动创建一个.java 的文件
这里写图片描述
接着就是写Server端的服务了

package com.example.server;
import com.example.server.aidl.IAdd;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class MyService extends Service {


    @Override
    public IBinder onBind(Intent intent) {
        // TODO 自动生成的方法存根
        return add;
    }
    IAdd.Stub  add=new IAdd.Stub() {

        @Override
        public int add(int i, int j) throws RemoteException {
                int sum=i+j;
                Log.e("ethan", "sum=="+sum);
            return sum;
        }
    };
}

服务内部没有特别的东西,就是实例化一个IAdd的接口对象,然后把该对象转换成IBinder类型的对象(stub方法就是干这事的)。之后通过onBind()方法返回 ,实例化并转化类型过后的对象add。

由于是跨进程启动,所以需要隐式启动服务。因此在Manifest中给服务注册上Action

 <service android:name="com.example.server.MyService">
            <intent-filter >
                <action android:name="com.example.server.MyService.MyAidl"/>
            </intent-filter>
        </service>

接下来就是客户端的代码实现了
首先把服务端的Aidl复制到客户端(连包名一起)
这里写图片描述
接着就是写MainActivity里面的代码了

public class MainActivity extends Activity implements OnClickListener {
    private Button button1,button2;
    private IAdd add;
    ServiceConnection conn=new ServiceConnection() {        
        @Override
        public void onServiceDisconnected(ComponentName name) {     
        }   
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            add=IAdd.Stub.asInterface(service);     
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initViews();
    }
    private void initViews() {
        // TODO 自动生成的方法存根
        button1=(Button) findViewById(R.id.button1);
        button2=(Button) findViewById(R.id.button2);
        button1.setOnClickListener(this);
        button2.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
    switch (v.getId()) {
    case R.id.button1:
        bindService(new Intent("com.example.server.MyService.MyAidl"), conn, BIND_AUTO_CREATE);
        break;
    case R.id.button2:
        try {
            add.add(3, 2);
        } catch (RemoteException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
        break;
    }

    }

在MainActivity里面,首先注册两个按钮,一个用来绑定Service,一个用来调用远程服务。接着实例化一个ServiceConnection的对象conn,然后在button1的点击事件里,执行bindService,bindServic
e的三个参数分别为隐式地洞Service的intent,ServiceConnection的实例化对象conn,以及flag参数。当执行完该方法后,会回调ServiceConnection里面的public void onServiceConnected(ComponentName name, IBinder service) 提供一个IBinder 的对象service回来,这个service其实是BinderProxy类型,然后调用aidl接口将service转换成IAdd类型的对象add。
于是就可以通过add,调用IAdd接口里面的方法了。
接着点击button2,执行接口IAdd接口里面的add方法。

    case R.id.button2:
        try {
            add.add(3, 2);
        } catch (RemoteException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
        break;

接着,控制台顺利打印出Log sum=5。证明调用远程服务成功了。

 E/ethan(2015): sum==5

回看AIDL的使用过程,其实和IPC(一)使用纯Binder进行进程间通信
大体上差不多,AIDL其实就是把Binder中的transact函数封装到了IAdd接口内部。上文拿到的IAdd的接口对象add,实际上是BinderProxy(实现了IBinder接口)的对象转化过来的,也就是把BinderProxy对象封装到了IAdd接口对象内部。当我们调用add.add()方法时候,内部还是调用的BinderProxy中的transact()方法来发送数据的。

下篇IPC(五)——浅谈AIDL的架构原理

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值