一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
初次接触使用AIDL,之前在项目中没有使用过,今天就来简单分享一下安卓中的AIDL的使用,AIDL 是 Android Interface Definition language 的缩写,它是⼀种 Android 内部进程通信接⼝的描述语⾔,通过它我们可以定义进程间的通信接⼝。那么既然是跨进程的我们就是编写2个程序用来模拟跨进程通讯。
文章进行更新,添加callBack,进行打包aar(包含aidl文件),供clinet(clinet将不在单独引入aidl文件)使用
服务端程序(被调用的程序)
首先我们创建一个安卓project,命名为service,我们在android studio中将项目架构,切换为project,随后我们在main文件夹下右键创建Diretcory,可直接选中aidl文件夹进行创建如图所示:
接下来我们进行创建aidl文件,我们可以在aidl文件夹上右键进行创建如图所示:
创建完成后我们创建一个方法,就用来计算2个数求和使用:
// MyAidlInterface.aidl
package com.glc.service;
// Declare any non-default types here with import statements
interface MyAidlInterface {
/**
* 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);
//求和
int getAdd(int num1,int num2);
}
在这里定义好AIDL类之后我们要sync project,这样我们才能找到构建的AdiL代码。 我们接下来在项目代码中在创建Service文件,如下图所示:
在Service中创建内部类,继承自Aidl类的抽象类Stub(这里必须要构建一下项目,否则找不到AIDL类),然后我们实现类里面的方法,这时就有我们定义的求和方法,我们实现求和方法里面的逻辑代码,让num1,num2相加,最后return,最后我们在Service的onBind()方法中返回内部类的实例。
public class MyService extends Service {
private static final String TAG = "MyService";
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
return new MyAidl();
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate: ");
}
private class MyAidl extends MyAidlInterface.Stub{
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
}
/**
* 求和
* @param num1
* @param num2
* @return result
* @throws RemoteException
*/
@Override
public int getAdd(int num1, int num2) throws RemoteException {
return num1+num2;
}
}
}
这样我们Service服务端代码就告一段落啦。
客户端程序(调用程序)
在客户端程序中我们也要引入AIDL文件,我们直接copy,服务端的AIDL文件夹即可(这里的包名路径要和服务端的AIL文件保持一致),完成之后我们同样要构建一下项目,如图所示:
接下来我们在Activity类中进行绑定服务,然后调用服务端的求和方法,进行得到2个数的值:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private MyAidlInterface myAidlInterface;
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding=ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
//绑定Aidl服务
bindMyService();
//获取结果按钮
binding.btnGetResult.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
int add = myAidlInterface.getAdd(1, 1);
binding.tvResult.setText("结果:"+add);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
private void bindMyService() {
Log.d(TAG, "bindMyService: ");
Intent intent=new Intent();
//包名、类名
intent.setComponent(new ComponentName("com.glc.service","com.glc.service.MyService"));
bindService(intent, new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.d(TAG, "onServiceConnected: ");
myAidlInterface = MyAidlInterface.Stub.asInterface(iBinder);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.d(TAG, "onServiceDisconnected: ");
myAidlInterface=null;
}
},BIND_AUTO_CREATE);
}
}
这样我们就完成服务端和客户端的代码,我们运行2个项目到设备,点击获取结果就能得到想要结果了。 github:github.com/GAOli-cong/…
在aidl中进行回调处理
在原先代码的基础上进行了修改,并且进行封装aar包(将aidl文件封装进了aar包),此时客户端的代码将不用在单独引用一遍aidl文件/同时通过callBack进行将数据回调。
首先创建ICallBack.aidl
在service的主模块代码中,新创建ICallBack.aidl 如下图:
在MyAidlInterface.aidl,新创建一个方法带有ICallBack参数
同时service中进行修改,实现新加的方法
service中新建module
在service中,新建module(用来打包aar供client使用),需要在module中,将aidl文件进行引用,如图所示:
同时新创建AidlManager文件,用来进行,调用aidl绑定服务
public class AidlManager {
private static final String TAG = "AidlManager";
private Context mContext;
private MyAidlInterface myAidlService;
private IBinder b;
private static AidlManager mInstance;
private boolean connected;
private AidlManager(Context context) {
mContext = context.getApplicationContext();
bindService(connection);
}
public static synchronized AidlManager getInstance(Context context) {
if (mInstance == null) {
mInstance = new AidlManager(context);
}
return mInstance;
}
public void unBind() {
if (connected) {
mContext.unbindService(connection);
}
}
public MyAidlInterface getMyAidlService() {
if (myAidlService != null) {
return myAidlService;
}
myAidlService = MyAidlInterface.Stub.asInterface(b);
return myAidlService;
}
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "onServiceConnected: 绑定成功");
b = service;
connected = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "onServiceDisconnected: 绑定失败");
connected = false;
}
};
private void bindService(ServiceConnection serviceConnection) {
Log.d(TAG, "开始绑定服务bindService: ");
Intent intent = new Intent();
//包名、类名
intent.setComponent(new ComponentName("com.glc.service", "com.glc.service.MyService"));
mContext.bindService(intent, serviceConnection, BIND_AUTO_CREATE);
}
}
然后将module进行打包 aar,同时将打包好的aar引用到client项目中,此时就可以通过aar拿到service,进行调用service端代码了。
已经更新最新代码github:github.com/GAOli-cong/…