服务端
Person.aidl文件
app/src/main/aidl/com/example/demo/entity/Person.aidl
// Person.aidl
package com.example.demo.entity;
parcelable Person;
IRomteAidlInterface.aidl文件
app/src/main/aidl/com/example/demo/IRemoteAidlInterface.aidl
// IRomteAidlInterface.aidl
package com.example.demo;
// Declare any non-default types here with import statements
import com.example.demo.entity.Person;
interface IRemoteAidlInterface {
/**
* 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 setData(inout Person person);
int calculation(int anInt, int bnInt);
}
Person类
app/src/main/java/com/example/demo/entity/Person.kt
package com.example.demo.entity
import android.os.Parcel
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
class Person(
val mUserName: String? = null,
val mUserAge: Int? = null
): Parcelable {
fun readFromParcel(parcel: Parcel){
parcel.readString()
parcel.readInt()
}
}
RemoteService服务类
app/src/main/java/com/example/demo/ui/RemoteService.kt
package com.example.demo.ui
import android.app.Service
import android.content.Intent
import android.os.IBinder
import android.os.RemoteException
import android.util.Log
import com.example.demo.IRemoteAidlInterface
import com.example.demo.entity.Person
class RemoteService : Service() {
private var mPerson: Person? = null
override fun onCreate() {
super.onCreate()
Log.d("TAG", "onCreate Service success!")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d("TAG", "onStartCommand Service success!")
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
super.onDestroy()
Log.d("TAG", "onDestroy Service success!")
}
override fun onBind(intent: Intent?): IBinder {
Log.d("TAG", "onBind Service success!")
return RemoteBinder()
}
override fun onUnbind(intent: Intent?): Boolean {
Log.d("TAG", "onUnbind Service!")
return super.onUnbind(intent)
}
inner class RemoteBinder : IRemoteAidlInterface.Stub() {
override fun basicTypes(
anInt: Int,
aLong: Long,
aBoolean: Boolean,
aFloat: Float,
aDouble: Double,
aString: String?
) {
}
override fun setData(person: Person?) {
mPerson = person
}
override fun calculation(anInt: Int, bnInt: Int): Int {
Log.d("TAG", "calculation a + b + age = ${mPerson?.mUserAge}")
return anInt + bnInt + (mPerson?.mUserAge ?: 0)
}
}
}
AndroidManifest.xml
<service android:name="com.example.demo.ui.RemoteService"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.RESPOND_AIDL_MESSAGE">
</action>
</intent-filter>
</service>
客户端
以下文件和服务端相同,且放在相同位置
Person.aidl
IRomteAidlInterface.aidl
Person
绑定服务端
private fun bindRemoteService() {
Log.d("TAG", "bindRemoteService")
val serviceIntent = Intent()
serviceIntent.action = "android.intent.action.RESPOND_AIDL_MESSAGE"
serviceIntent.setPackage("com.example.demo")
bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE)
// 不知道package名时使用createExplicitFromImplicitIntent
// val newIntent = Intent(createExplicitFromImplicitIntent(this, serviceIntent))
// bindService(eintent, serviceConnection, Context.BIND_AUTO_CREATE)
}
private var iRemoteAidlInterface: IRemoteAidlInterface? = null
private var serviceConnection: ServiceConnection = object : ServiceConnection {
override fun onServiceConnected(componentName: ComponentName, iBinder: IBinder) {
Log.d("TAG", "onServiceConnected ${componentName.packageName}")
iRemoteAidlInterface = IRemoteAidlInterface.Stub.asInterface(iBinder)
}
override fun onServiceDisconnected(componentName: ComponentName) {
Log.d("TAG", "onServiceDisconnected ${componentName.packageName}")
iRemoteAidlInterface = null
}
}
调用服务端
private fun doSomething() {
iRemoteAidlInterface?.let {
it.setData(Person("mask", 100))
val calculation: Int = it.calculation(1, 2)
Log.d("TAG", " 结果: $calculation")
}
}
工具类
private fun createExplicitFromImplicitIntent(context: Context, implicitIntent: Intent?): Intent? {
// Retrieve all services that can match the given intent
val pm = context.packageManager
val resolveInfo = pm.queryIntentServices(implicitIntent!!, 0)
// Make sure only one match was found
if (resolveInfo == null || resolveInfo.size != 1) {
return null
}
// Get component info and create ComponentName
val serviceInfo = resolveInfo[0]
val packageName = serviceInfo.serviceInfo.packageName
val className = serviceInfo.serviceInfo.name
val component = ComponentName(packageName, className)
Log.d("TAG", "packageName = $packageName")
Log.d("TAG", "className = $className")
// Create a new intent. Use the old one for extras and such reuse
val explicitIntent = Intent(implicitIntent)
// Set the component to be explicit
explicitIntent.component = component
return explicitIntent
}
Android Studio中如何创建AIDL
AIDL中的in,out,inout理解
Service Intent must be explicit的两种解决方法