Android中的跨进程调用技术AIDL

时间:2023-03-08 19:28:03
Android中的跨进程调用技术AIDL

什么是AIDL

Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。

为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现。

与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口。

Android的四大组件中的三个(Activity、BroadcastReceiver和ContentProvider)都可以进行跨进程访问,另外一个Android应用程序组件Service同样可以。因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。

实现AIDL

建立AIDLServer和AIDLClient项目,如下图:

Android中的跨进程调用技术AIDLAndroid中的跨进程调用技术AIDL

① AIDLServer

新建一个ICalculate接口,并将文件后缀修改为.aidl

 package com.example.calculate;

 interface ICalculate {
double doCalculate(double a, double b);
}

.aidl编译后会在“gen/包名/”目录中生成ICalculate.java的接口文件

新建一个CalculateService服务,该服务中的MyBinder 实现了ICalculate接口

 public class CalculateService extends Service {

     private MyBinder mBinder;  

     @Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate(); mBinder = new MyBinder(); } @Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
} @Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return mBinder;
} public class MyBinder extends ICalculate.Stub
{ @Override
public double doCalculate(double a, double b) throws RemoteException {
// TODO Auto-generated method stub
return a+b;
} } }

AndroidManifest.xml中声明Service

  <service
android:name="com.example.aidlserver.CalculateService"
android:enabled="true" >
<intent-filter>
<action android:name="com.example.calculate.ICalculate" />
</intent-filter>
</service>

② AIDLClient

将AIDLServer中的com.example.calculate包拷入AIDLClient(跨进程调用必须包相同)

使用bindService方法来调用CalculateService服务

 ICalculate mBinder; 

     ServiceConnection mCon=new ServiceConnection() {

         @Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub } @Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
mBinder=ICalculate.Stub.asInterface(arg1); }
};

Intent intent=new Intent("com.example.calculate.ICalculate");

bindService(intent, mCon, Context.BIND_AUTO_CREATE);

MainActivity.java代码如下:

 public class MainActivity extends ActionBarActivity {

     Button btnPlus;
EditText et1;
EditText et2;
TextView tvResult; ICalculate mBinder; ServiceConnection mCon=new ServiceConnection() { @Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub } @Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
mBinder=ICalculate.Stub.asInterface(arg1); }
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); btnPlus=(Button) findViewById(R.id.btnPlus);
et1=(EditText) findViewById(R.id.et1);
et2=(EditText) findViewById(R.id.et2);
tvResult=(TextView) findViewById(R.id.tvResult); btnPlus.setOnClickListener(new OnClickListener() { @Override
public void onClick(View arg0) { if(mBinder==null)
{
return;
} String num1=et1.getText().toString();
String num2=et2.getText().toString(); if(TextUtils.isEmpty(num1)||TextUtils.isEmpty(num2))
{
return;
} double d1=Double.parseDouble(num1);
double d2=Double.parseDouble(num2); double total=-1; Log.i("MainActivity", "onClick() d1="+d1+" d2"+d2); try {
total=mBinder.doCalculate(d1, d2);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} tvResult.setText("结果:"+total); }
}); Intent intent=new Intent("com.example.calculate.ICalculate"); bindService(intent, mCon, Context.BIND_AUTO_CREATE); } @Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unbindService(mCon);
} }

注:bindService后记得unbindService