在 AIDL 中,可以使用 oneway、inout 和 out 等关键字来定义不同类型的方法参数。其中 oneway 表示单向通信,即只能由客户端向服务端发送请求。
build.gradle 配置问题
sourceSets {
main {
java.srcDirs[
'src\\main\\java',
'src\\main\\aidl',
]
}
}
buildFeatures {
dataBinding true
aidl true
}
service 启动问题
val intent = Intent().apply {
component = ComponentName("com.demo.arouter","com.demo.arouter.aidl.ComputeService")
action = "com.demo.aidl.ComputeService"
}
//8.0 后台启动问题
startForegroundService(intent)
bindService(intent, connection, Context.BIND_AUTO_CREATE )
//客户端AndroidManifest.xml配置包可见
// Android11
<queries >
<package android:name="com.demo.arouter"/>
<intent>
<action android:name="com.demo.aidl.ComputeService"/>
</intent>
</queries>
<service
android:name=".aidl.ComputeService"
android:exported="true"
android:enabled="true">
<!-- android:process=":compute">-->
<intent-filter>
<action android:name="com.demo.aidl.ComputeService" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
ComputeInterface.Stub
返回的IBinder 问题
- 本地访问,返回的是本地对象
- 远程访问service 是返回的代理对象proxy
- proxy 执行必须经过onTransact
public static com.demo.arouter.ComputeInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
//本地访问,返回的是本地对象
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.demo.arouter.ComputeInterface))) {
return ((com.demo.arouter.ComputeInterface)iin);
}
return new com.demo.arouter.ComputeInterface.Stub.Proxy(obj);
}
方法从1-N 按顺序写入,
热修复只能从后追加方法,而不能打乱顺序,
int FIRST_CALL_TRANSACTION = 0x00000001;
static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_addTwo = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_addCompute = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_getCompute = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
static final int TRANSACTION_getComputeForClientIn = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
static final int TRANSACTION_getComputeForClientOut = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
static final int TRANSACTION_getComputeForClientInOut = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6);
class ComputeBinder : ComputeInterface.Stub() {
override fun add(a: Int) {
log("ComputeBinder add 调用了- a: $a")
}
override fun addTwo(a: Int, b: Int): Int {
log("ComputeBinder addTwo 调用了- a: $a , b: $b")
return a + b;
}
override fun addCompute(c: Compute?): Int {
log("ComputeBinder addCompute 调用了- c: ${c.toString()}")
c ?: return 0
return c.a * c.b
}
override fun getCompute(a: Int, b: Int): Compute {
log("ComputeBinder getCompute 调用了- a: $a , b: $b")
return Compute(a + 1, b + 1)
}
override fun getComputeForClientIn(c: Compute?): Compute {
log("ComputeBinder getComputeForClient 调用了- a: ${c?.a} , b: ${c?.b}")
return c?.copy(a = 111, b = 222)?:Compute(1000,10000)
}
override fun getComputeForClientOut(c: Compute?): Compute {
log("ComputeBinder getComputeForClientOut 调用了- a: ${c?.a} , b: ${c?.b}")
return c?.copy(a = 111, b = 222)?:Compute(1000,10000)
}
override fun getComputeForClientInOut(c: Compute?): Compute {
log("ComputeBinder getComputeForClientInOut 调用了- a: ${c?.a} , b: ${c?.b}")
return c?.copy(a = 111, b = 222)?:Compute(1000,10000)
}
override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean {
val flag = super.onTransact(code, data, reply, flags)
log(
"""
ComputeBinder onTransact调用了
code : $code
data : $data
reply : $reply
flags : $flags
onTransact : $flag
""".trimIndent()
)
return flag
}
fun log(msg: String) {
Log.e("TAG", "aidl-- $msg")
}
}
in,out,intout 定向tag 问题
- in :user 服务端完整读取,不会写入客户端 ,user不变
- out : user 服务端不会读取,但会写入客户端, user改变
- intout : user服务端完整读取,完整写入客户端 user改变
Compute getComputeForClientIn(in Compute c);
Compute getComputeForClientOut(out Compute c);
Compute getComputeForClientInOut(inout Compute c);
日志
oneWay
oneway void onewayMethod(int param);
oneway是一种用于 AIDL 方法的修饰符,表示非阻塞调用。- 适用场景:不需要返回结果的调用,或需要提高性能的场景。
- 限制:
oneway方法必须返回void,且不能有inout或out参数。 - 注意事项:
oneway方法不会抛出异常,且调用顺序可能与执行顺序不一致。
通过合理使用 oneway,可以优化跨进程通信的性能和响应速度。
kotlin 序列化 问题 Compute
readFromParcel()需要手动添加, kotlin默认CREATOR写入,重新创建对象,达不到 out inout 输出的效果
package com.demo.arouter
import android.os.Parcel
import android.os.Parcelable
data class Compute(var a: Int = 0, var b: Int = 0) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readInt(),
parcel.readInt()
) {
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeInt(a)
parcel.writeInt(b)
}
//需要
fun readFromParcel(parcel: Parcel){
a = parcel.readInt()
b = parcel.readInt()
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<Compute> {
override fun createFromParcel(parcel: Parcel): Compute {
return Compute(parcel)
}
override fun newArray(size: Int): Array<Compute?> {
return arrayOfNulls(size)
}
}
}