一.实现的功能:app222客户端通过binder调用app111服务端的实现接口
二.步骤
目录图:
1.建立工程app111
2.添加User.aidl,ABBean.aidl,TestBean.aidl
这里需要特别注意,业务aidl名字你随便取无所谓,比如这里的User.aidl,但是ABBean.aidl和TestBean.aidl必须和自定义的数据类型名一致,一个自定类型一个aidl文件,而且自定义类型数据必须实现序列化,这里又要注意反正我使用@Parcelize是无效的,最后还是老老实实的去实现Parcelable接口。
User.aidl
// User.aidl
package com.example.app111;
import com.example.app111.TestBean;
import com.example.app111.AABean;
// Declare any non-default types here with import statements
interface User {
/**
* 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);
String getString();
TestBean getTestBean();
AABean getAABean();
}
ABBean.aidl
package com.example.app111;
parcelable AABean;
TestBean.aidl
// TestBean.aidl
package com.example.app111;
parcelable TestBean;
TestBean.kt,这里一个文件就行
package com.example.app111
import android.os.Parcel
import android.os.Parcelable
//使用@Parceble有问题,不要用,反正也就是ALT+ENT的事
data class TestBean(var name:String? ="",var age:Int = 10):Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readInt()
) {
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(name)
parcel.writeInt(age)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<TestBean> {
override fun createFromParcel(parcel: Parcel): TestBean {
return TestBean(parcel)
}
override fun newArray(size: Int): Array<TestBean?> {
return arrayOfNulls(size)
}
}
}
data class AABean(var name:String? ="",var age:Int = 10):Parcelable{
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readInt()
) {
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(name)
parcel.writeInt(age)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<AABean> {
override fun createFromParcel(parcel: Parcel): AABean {
return AABean(parcel)
}
override fun newArray(size: Int): Array<AABean?> {
return arrayOfNulls(size)
}
}
}
这里要rebuild project,再往下。
在MainActivity中实现一个Servie继承类,内部类继承User.Stub()类,并实现接口
class MyService :Service(){
override fun onBind(intent: Intent?): IBinder? {
return MyBinder()
}
inner class MyBinder : User.Stub() {
override fun basicTypes(anInt: Int, aLong: Long, aBoolean: Boolean, aFloat: Float, aDouble: Double, aString: String?) {
}
override fun getString(): String {
return "App111 Test"
}
override fun getTestBean(): TestBean {
return TestBean("luo",220)
}
override fun getAABean(): AABean {
return AABean("luo",34)
}
}
}
注册service:
<service android:name=".MyService"
android:enabled="true"
android:exported="true"
>
<intent-filter>
<action android:name="com.example.app111"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
App222中
目录:
将app111中的aidl文件复制到main中,同时新建相同的包名com.example. app111,将app111中的TestBean.kt复制过来。
然后rebuild project
最后在MainActivity中实现连接
var user:User? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var intent = Intent()
intent.action = "com.example.app111" //MyService注册时的Action名
intent.`package`="com.example.app111" //app111所在的package名
bindService(intent,object :ServiceConnection{
override fun onServiceDisconnected(name: ComponentName?) {
}
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
user = User.Stub.asInterface(service)
var testBean = user!!.testBean
var aaBean = user!!.aaBean
test.text = testBean.name+aaBean.age
}
},Context.BIND_AUTO_CREATE)
}
最后效果
这里啰嗦几句,就是一定要保证两个app工程的aidl所在包名一致,bean类所在包名也一致,而且bean类所在包名与aidl包名也必须一致。(一句话,两个app的aidl文件和bean类包名都一样,包名一样,但是目录却不一样的,一个时aidl目录,一个时java目录)
一个自定义类型对应一个aidl文件(除了业务aidl文件外),而且名字一致。