IPC_Aidl的基本使用过程
Posted 從前以後
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的基本使用过程的主要内容,如果未能解决你的问题,请参考以下文章
iOS唯一的遗憾是太短了!不愧是App Store年度最佳游戏《甜甜圈都市》