Android系统的进程之间不能共享内存,所以需要提供一些机制在不同的进程之间进行数据的交互。接下来本文就简单地介绍如何使用AIDL进行Android程序之间的跨进程访问。
1、什么是AIDL
大多数情况下我们在程序中自己实现的Service只能供自己的程序调用,其他程序是不能使用的。为了使其他的程序可以访问本地程序提供的服务,Android系统采用了RPC的方式来实现。Android使用AIDL(Android Interface Definition Language)来定义并公开服务的接口。
2、如何创建AIDL
创建的过程很简单,其实就是定义一个aidl文件,然后实现该文件定义的接口,然后发布接口,将服务运行在手机上,手机上的其他程序就可以访问你创建的服务了。
3、具体AIDL服务的创建过程
新建一个TestAIDL工程,在src目录下创建一个名为ITestService.aidl的文件。如上图所示,在aidl文件中定义两个方法。
package com.example.testaidl;
interface ITestService{
String getValue();
int calculateAdd(int a, int b);
}
注意方法不能加修饰符(如public、private等)以及AIDL不支持的数据类型
如果aidl文件的输入正确,那么adt公交会在gen目录下生产ITestService.java,一般情况下我们不用管这个文件,也不需要维护它。
然后我们需要用一个Service来提供aidl的实例。
创建一个TestService类,继承Service。在TestService中定义一个内嵌类来继承ITestService.Stub,TestService类的代码如下:
package com.example.testaidl;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class TestService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return new TestServiceImpl();
}
public class TestServiceImpl extends ITestService.Stub{
@Override
public String getValue() throws RemoteException {
// TODO Auto-generated method stub
return "This is a value from aidl";
}
@Override
public int calculateAdd(int a, int b) throws RemoteException {
// TODO Auto-generated method stub
return a+b;
}
}
}
看到了,我们在aidl中定义的两个方法是在TestServiceImpl中实现的。另外onBind方法需要返回一个TestServiceImpl的实例对象,否则的话调用者无法获得服务对象。
最后要做的就是在manifest文件中声明TestService
<service android:name=".TestService">
<intent-filter>
<action android:name="com.example.testaidl.ITestService"/>
</intent-filter>
</service>
注意,action中的name “com.example.testaidl.ITestService”就是其他程序访问aidl服务时需要传的ID
之后把该工程run到你的手机上,这个服务就可以被其他的程序访问了。
4、调用程序的创建
为了查看我们的AIDL服务是否创建成功,我们可以写一个测试程序TestAIDLClient来验证一下
新建一个相同的包名com.example.testaidl,然后把ITestService.java直接拷贝过来。
然后在MainActivity中绑定并调用aidl服务中的方法
MainActivity的代码如下:
package com.example.testaidlclient;
import com.example.testaidl.ITestService;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener{
private ITestService testService;
private Button bindBtn;
private Button invokeBtn;
private TextView showText;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
testService = ITestService.Stub.asInterface(service);
invokeBtn.setEnabled(true);
Toast.makeText(getApplicationContext(), "绑定成功", Toast.LENGTH_SHORT).show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
bindBtn = (Button) findViewById(R.id.bind_btn);
invokeBtn = (Button)findViewById(R.id.invoke_btn);
//初始化不能点击,绑定成功之后可以点击
invokeBtn.setEnabled(false);
showText = (TextView) findViewById(R.id.show_text);
bindBtn.setOnClickListener(this);
invokeBtn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.bind_btn:
bindService(new Intent("com.example.testaidl.ITestService"), serviceConnection, Context.BIND_AUTO_CREATE);
break;
case R.id.invoke_btn:
try {
showText.setText(testService.getValue() + testService.calculateAdd(10, 20));
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
}
首先点击绑定按钮进行绑定,系统通过serviceConnection的onServiceConnected方法获得aidl服务对象,然后通过对象调用aidl服务的具体方法。运行截图如下:
最后是两个工程的下载链接