前言:
众所周知android进程间的通信方式有很多种,比如 服务 广播 activity 内容共享者 aidl ,今天我们要说的是aidl的进程间通信方式。
Aidl (Android 接口描述语言):
是底层基于android binder机制的一种进程间的通信方式,我们可以使用Aidl 让 A 应用程序 和 B应用程序进行通信,传输数据。
Aidl 实列程序编写
1.应用程序设计:
1.设计2个应用 一个应用服务端A 一个客服端应用B
2. 应用B 向 应用 A 发送数据,应用A对数据进行处理,并且显示出处理后的数据结果。
2.根据应用程序设计进行Aidl 编写步骤分解
我将Aidl 程序分解为5个步骤:
1.服务端A定义aidl接口。
2.服务端A服务类实现aidl接口方法,在onBinder方法种return aidl接口对象。
3.service定义action
4.客服端B将服务端的aidl接口复制到客服端(包名也要一样)。
5.客服端B bindservice启动服务,获取到服务A的Ibinder然后进行方法的调用。
3.代码实列
1.服务端A 定义aidl接口:
在main文件夹下新建aidl文件夹,再新建aidl接口文件,新建完成之后最好Rebuild 一下项目,这样才能找到aidl接口文件。
interface IMyAidlInterface {
/**
* 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);
void receiveMsg(String msg);
}
这里我定义了一个接口receiveMsg方法。
2.服务端A服务类实现aidl接口方法,在onBinder方法种return aidl接口对象。
package com.xgimi.tvwidget;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;
public class AidlService extends Service {
private ServiceBinder mServiceBinder;
private final static String TAG = "AidlService";
/**
* 返回服务的IBinder实列
*
* @param intent
* @return
*/
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind: ");
return mServiceBinder;
}
/**
* 服务第一次启动的时候new出IBinder的实列
*/
@Override
public void onCreate() {
super.onCreate();
if (mServiceBinder == null) {
mServiceBinder = new ServiceBinder();
}
Log.d(TAG, "onCreate: ");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ");
}
private Handler mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
String msgTxt = String.valueOf(msg.obj);
Toast.makeText(getApplicationContext(), msgTxt, Toast.LENGTH_LONG).show();
return false;
}
});
/**
* 实现Aidl的接口
*/
class ServiceBinder extends IMyAidlInterface.Stub {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString)
throws RemoteException {
}
@Override
public void receiveMsg(String msg) throws RemoteException {
Message message = Message.obtain();
message.obj = msg;
mHandler.sendMessage(message);
Log.d(TAG, "receiveMsg: " + msg);
}
}
}
3.service定义action
android:process=":aidl" 此条属性代表让一个服务在一个远端进程中运行(而不是标准的它所在的apk的进程中运行)
<service
android:name=".AidlService"
android:exported="true"
android:process=":aidl">
<intent-filter>
<action android:name="com.android.AidlService" />
</intent-filter>
</service>
4.客服端B将服务端的aidl接口复制到客服端(包名也要一样)。
将服务端A的aidl整个文件直接cp到客服端B的main下面 如图所示
5.客服端B bindservice启动服务,获取到服务A的Ibinder然后进行方法的调用。
package zoomtest.xgimi.com.tvwidget;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.xgimi.tvwidget.IMyAidlInterface;
public class ClientBActivity extends AppCompatActivity {
private ServiceConnection mServiceConnection;
private IMyAidlInterface mMyAidlInterface;
private final static String TAG = "ClientBActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
try {
mMyAidlInterface.receiveMsg("连接成功调用服务端receiveMsg方法");
} catch (RemoteException e) {
e.printStackTrace();
}
Log.d(TAG, "onServiceConnected: 获取到服务端的IBinder");
}
@Override
public void onServiceDisconnected(ComponentName name) {
mMyAidlInterface = null;
}
};
startBinderServiveA();
}
private void startBinderServiveA() {
Intent startIntent = new Intent();
//设置服务端应用设置A的包名
startIntent.setPackage("com.xgimi.tvwidget");
//设置服务端应用设置A的action
startIntent.setAction("com.android.AidlService");
//通过bindService的方法启动A服务
bindService(startIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
}
我们通过bindService启动服务A,在onServiceConnected 连接成功中拿到服务端A的IBinder,就能调用服务的receiveMsg方法,就实现了2个进程之间的数据通信。我通过receiveMsg方法发送了字符串 “连接成功调用服务端receiveMsg方法”。
点击启动客服端B应用后 如图所示 服务A应用依次打印出了 onCreate onBind 和 receiveMsg方法接收到客服端B的数据。
当我们关闭客服端B时
如图所示服务端A打印出了 onDestroy 由此 我们可知如果我们客服端B退出了,那么服务端A也会跟着退出。
总体来说这个是aidl的基本用法,使用起来也是比较简单的。