由于每个应用程序都运行在自己的进程空间,并且可以从应用程序UI运行另一个服务进程,而且经常会在不同的进程间传递对象。在Android平台,一个进程通常不能访问另一个进程的内存空间。但是android提供了AIDL可以用来进程间数据传递。
AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。
AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。它是使用代理类在客户端和实现端传递数据。
下面通过一个实例来演示AIDL,因为是进程之间数据传递,所以这里要使用建立android工程,一个是AIDL的服务端另一个是客户端.
一、新建项目com.lemon.testaidlserver,并在src或者app目录上右键创建PayAidlInterface.aidl:
interface PayAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
int calculation(int anInt, int bnInt);
}
Make Module "app",这时会在app\build\generated\source\aidl..下生成PayAidlInterface.java
二、新建service,并配置minifest.xml
public class MAIDLService extends Service {
@Override
public IBinder onBind(Intent t) {
Log("service on bind");
return new MyBinder();
}
class MyBinder extends PayAidlInterface.Stub{
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
Log("get data from client:" + anInt + " " + aLong);
}
@Override
public int calculation(int anInt, int bnInt) throws RemoteException {
Log(anInt + "--" + bnInt);
return anInt+bnInt;
}
}
private void Log(String str) {
Log.e("==============>", "----------" + str + "----------");
}
}
<service android:name="com.lemon.testaidlserver.MAIDLService">
<intent-filter>
<action android:name="com.lemon.testaidlserver.MAIDLService" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
三、新建项目com.lemon.testaidlclient,并直接将上个应用中的mian/aidl复制过来:
四、在activity中使用:
public class MainActivity extends AppCompatActivity {
PayAidlInterface service;
TextView tv_result;
EditText ed_num_1;
EditText ed_num_2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_result=(TextView)findViewById(R.id.tv_result);
ed_num_1=(EditText)findViewById(R.id.ed_num_1);
ed_num_2=(EditText)findViewById(R.id.ed_num_2);
//使用意图对象绑定开启服务
Intent intent = new Intent();
//在5.0及以上版本必须要加上这个
intent.setPackage("com.lemon.testaidlserver");
intent.setAction("com.lemon.testaidlserver.MAIDLService");//这个是上面service的action
bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
public void onCalculate(View v){
if (TextUtils.isEmpty(ed_num_1.getText().toString())||TextUtils.isEmpty(ed_num_2.getText().toString())){
return;
}
int num1=Integer.parseInt(ed_num_1.getText().toString());
int num2=Integer.parseInt(ed_num_2.getText().toString());
if(service != null){
try {
int calculation = service.calculation(num1, num2);
tv_result.setText(calculation+"");
} catch (RemoteException e) {
e.printStackTrace();
tv_result.setText(e.toString());
}
}
}
@Override
protected void onDestroy () {
super.onDestroy();
if (mServiceConnection != null) {
unbindService(mServiceConnection);
}
}
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName arg0) {
Log.e("==============>", "onServiceDisconnected:" + arg0.getPackageName());
}
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
Log.e("==============>", "onServiceConnected:" + name.getPackageName());
// 获取远程Service的onBinder方法返回的对象代理
service = PayAidlInterface.Stub.asInterface(binder);
}
};