AIDL 的全称是 Android Interface Definition Language(安卓接口定义语言)
下面三四是重点,一二五给大家作为补充
一、同应用启动 Service
startService(new Intent(this,AppService.class));
二、跨应用启动 Service
Intent serviceIntent = new Intent();
serviceIntent.setComponent(new ComponentName("com.example.test", "com.example.test.BookManagerService"));
startService(serviceIntent);
ComponentName 的两个参数:第一个参数是另外一个应用的包名,第二个参数是另外一个应用的Service 所在的位置
还有,被启动的Service需要在所在的项目的AndroidManifest.xml中声明Service权限,exporter的属性为true,否则不能跨应用启动
三、跨应用绑定 Service
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
System.out.println("----服务已绑定");
IBookManager iBookManager = IBookManager.Stub.asInterface(iBinder);
try {
List<Book> list = iBookManager.getBookList();
Log.i("书的信息:", list.toString());
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
System.out.println("service disconnected");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_01 = findViewById(R.id.btn_01);
System.out.println("__________________client-------------------------");
btn_01.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.example.test", "com.example.test.BookManagerService"));
bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
});
}
四、AIDL 的通信流程
一、服务端
1.服务端首先要创建一个 Service 用来监听客户端的连接请求
2.然后创建一个 AIDL 文件,将暴露给客户端的接口在这个 AIDL 文件中声明
3.最后在 Service 中实现这个 AIDL 接口即可。
二、客户端
首先需要绑定服务端 Service(建立连接 ServiceConnection),绑定成功后,将服务端返回的 Binder 对象转成所属的类型,接着就可以调用 AIDL 中的方法了。
== AppA是服务端,AppB是客户端,AppA使用aidl传递身高数据给AppB的代码示例==
首先,我们需要定义一个AIDL接口,用于在AppA和AppB之间传递身高数据。
在AppA中的AIDL文件(例如,IServerInterface.aidl):
// 定义一个包含获取身高数据方法的接口
interface IServerInterface {
// 获取身高数据的方法
float getHeight();
}
然后,在AppA中创建一个Service,并实现这个AIDL接口:
public class HeightService extends Service {
// 实现AIDL接口
private final IServerInterface.Stub mBinder = new IServerInterface.Stub() {
@Override
public float getHeight() throws RemoteException {
// 在这里返回身高数据,这里只是一个简单的示例,实际情况可能需要从数据库或其他地方获取数据
return 180.5f; // 假设身高是180.5厘米
}
};
@Override
public IBinder onBind(Intent intent) {
// 返回实现了AIDL接口的Binder对象
return mBinder;
}
}
在AndroidManifest.xml中注册Service:
<service android:name=".HeightService">
<intent-filter>
<action android:name="com.example.appa.IServerInterface"/>
</intent-filter>
</service>
接下来,在AppB中需要使用AIDL接口来获取身高数据。首先,需要在AppB中创建一个与AppA相同的AIDL文件:
// 在AppB中创建与AppA相同的AIDL文件,以便能够调用AppA中的接口
然后,在AppB中创建一个与AIDL接口匹配的ServiceConnection,以连接到AppA中的Service,并通过AIDL接口获取身高数据:
public class HeightServiceConnection implements ServiceConnection {
// AIDL接口实例
private IServerInterface heightService;
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 获取AIDL接口实例
heightService = IServerInterface.Stub.asInterface(service);
try {
// 调用AppA中的方法获取身高数据
float height = heightService.getHeight();
// 处理获取到的身高数据,这里只是一个简单的示例
Log.d("AppB", "Height received from AppA: " + height + " cm");
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
// 断开连接时的处理
heightService = null;
}
}
最后,在AppB中启动Service,并绑定到AppA中的Service:
// 启动Service,并绑定到AppA中的Service
HeightServiceConnection connection = new HeightServiceConnection();
Intent intent = new Intent("com.example.appa.IServerInterface");
intent.setPackage("com.example.appa"); // AppA的包名
bindService(intent, connection, Context.BIND_AUTO_CREATE);
记得在不需要使用Service时解绑:
unbindService(connection);
通过这样的方式,AppB就可以通过AIDL接口与AppA通信,并获取AppA提供的身高数据。
五、startService()和bindService()区别
1.执行startService时,Service会经历onCreate->onStartCommand
。
当执行stopService时,直接调用onDestroy方法。调用者如果没有stopService,Service会一直在后台运行,下次调用者再起来仍然可以stopService。
2.执行bindService时,Service会经历onCreate->onBind
。这个时候调用者和Service绑定在一起。调用者调用unbindService方法或者调用者Context不存在了(如Activity被finish了),Service就会调用onUnbind->onDestroy。这里所谓的绑定在一起就是说两者共存亡了。
3.多次调用startService,该Service只能被创建一次,即该Service的onCreate方法只会被调用一次。但是每次调用startService,onStartCommand方法都会被调用。Service的onStart方法在API 5时被废弃,替代它的是onStartCommand方法。
4.第一次执行bindService时,onCreate和onBind方法会被调用,但是多次执行bindService时,onCreate和onBind方法并不会被多次调用,即并不会多次创建服务和绑定服务。