AIDL是什么:
AIDL是Android Interface definition language(Android接口定义语言)的缩写,由于不同进程间不能共享内存,为了解决进程间通信的问题,可以通过AIDL接口语言来实现进程间的通信。让你可以在自己的APP里绑定一个其他APP的service,这样你的APP可以和其他APP交互。
简单使用:
因为是不同APP交互么,所以首先创建项目A(服务端) 和项目B(客户端)
在A项目中创建aidl
// Declare any non-default types here with import statements
interface IMyAidlInterface {
/**
* 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);
//添加新方法getString
String getName();
}
系统会自动生成一个aidl文件
我们在上面添加一个方法getName()
然后bulid项目就会在build文件夹中自动生成我们想要的文件
在项目A中创建Service
class MyService : Service() {
override fun onBind(intent: Intent): IBinder {
return MyBinder()
}
internal class MyBinder : IMyAidlInterface.Stub() {
override fun basicTypes(
anInt: Int,
aLong: Long,
aBoolean: Boolean,
aFloat: Float,
aDouble: Double,
aString: String?
) {}
override fun getName(): String {
return "aidl"
}
}
}
在service里面创建一个内部类,继承你刚才创建的AIDL的名称里的生成的Stub类,并实现接口方法,在onBind返回内部类的实例。 这个我们返回String "aidl"
在项目B中启动服务
拷贝项目A中的aidl文件夹到项目B 保证包名一致
然后在Activity中启动服务
class AidlActivity : AppCompatActivity() {
val tag="AidlActivity"
private var textView: TextView? = null
private var iMyAidlInterface: IMyAidlInterface? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
textView = findViewById(R.id.text)
val intent = Intent()
intent.component = ComponentName("com.song.aidl", "com.song.aidl.MyService")
bindService(intent, object : ServiceConnection {
override fun onServiceDisconnected(arg0: ComponentName) {
iMyAidlInterface = null
Log.e(tag, "null")
}
override fun onServiceConnected(arg0: ComponentName, arg1: IBinder) {
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(arg1)
if (iMyAidlInterface == null) {
Log.e(tag, "fail")
} else {
Log.e(tag, "success")
}
}
}, BIND_AUTO_CREATE)
startService(intent) //启动service
textView?.setOnClickListener {
if (iMyAidlInterface == null) {
Toast.makeText(this, "get service Fail", Toast.LENGTH_SHORT).show()
} else {
try {
Toast.makeText(this, iMyAidlInterface!!.name, Toast.LENGTH_SHORT).show()
} catch (e: RemoteException) {
e.printStackTrace()
}
}
}
}
}
点击获取项目A返回的String "aidl"
注意事项
通过Action启动指定注册的Service android6.0之后是无效的了,bindservice的过程 由于高版本的Android 限制了隐式Intent启动Service,需要指定包名和类名。如
intent.component = ComponentName("com.song.aidl", "com.song.aidl.MyService")
服务端的service 需要在添加android:process=":remote"