当前位置:网站首页>Aidl basic use
Aidl basic use
2022-07-01 21:46:00 【Liu Yichu】
One 、 Approximate process
1. Server creation .aidl file
2. Defining interfaces
3.build Generate corresponding java file
4. Expose the interface to the client ( Write a service, rewrite onBind(), return Stub The realization of the class )
5. Copy aidl Documents and corresponding bean class ( If any ) To client
6. client binderService Get binder Instance calls server method .
Example :
1. The service side in src/main Create aidl file IPersonManager.aidl
// IPersonManager.aidl
package com.lmy.androidutilcode;
import com.lmy.androidutilcode.bean.Person;
interface IPersonManager {
List<Person> getPersonList();
boolean addPerson(inout Person person);
}
2. Define the object to be transferred Person
class Person(var name: String? = "") : Parcelable {
constructor(parcel: Parcel) : this(parcel.readString())
override fun toString(): String {
return "Person(name=$name) hashcode = ${hashCode()}"
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(name)
}
fun readFromParcel(parcel: Parcel) {
this.name = parcel.readString()
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<Person> {
override fun createFromParcel(parcel: Parcel): Person {
return Person(parcel)
}
override fun newArray(size: Int): Array<Person?> {
return arrayOfNulls(size)
}
}
3. Then you have to aidl Of Same directory I also need to declare this Person object . Create a new one Person.aidl
package com.xfhy.allinone.ipc.aidl;
parcelable Person;
Pictured :

4.rebuild once ,AS The following code will be generated automatically IPersonManager.java.
Be careful :aidl It is better not to use Chinese Notes in the document
5. The server exposes the interface like the client
Define a Service, And then take it. process Set up a new process , Separate from the main process ( Or like I use here 2 individual module, namely 2 individual application). Simulate cross process access , It needs to realize .aidl Generated interfaces
class RemoteService : Service() {
private val mPersonList = mutableListOf<Person?>()
private val mBinder: Binder = object : IPersonManager.Stub() {
override fun getPersonList(): MutableList<Person?> = mPersonList
override fun addPerson(person: Person?): Boolean {
return mPersonList.add(person)
}
}
override fun onBind(intent: Intent?): IBinder? {
return mBinder
}
override fun onCreate() {
super.onCreate()
mPersonList.add(Person("Garen"))
mPersonList.add(Person("Darius"))
}
}
Realized IPersonManager.Stub It's a Binder, Need to pass through onBind() return , The client needs to pass this Binder To call... Across processes Service The service here .
6. Copy aidl Documents and corresponding bean Object to client
Be careful : The directory structure should be exactly the same 
7. Client calls
class AidlActivity : TitleBarActivity() {
companion object {
const val TAG = "lmy"
}
private var remoteServer: IPersonManager? = null
private val serviceConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
log(TAG, "onServiceConnected")
// stay onServiceConnected call IPersonManager.Stub.asInterface Get an instance of the interface type
// Call the service of the server through this instance
remoteServer = IPersonManager.Stub.asInterface(service)
}
override fun onServiceDisconnected(name: ComponentName?) {
log(TAG, "onServiceDisconnected")
}
}
override fun getThisTitle(): CharSequence {
return "AIDL"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_aidl)
btnConnect.setOnClickListener {
connectService()
}
btnGetPerson.setOnClickListener {
getPerson()
}
btnAddPerson.setOnClickListener {
addPerson()
}
}
private fun connectService() {
val intent = Intent()
//action and package(app The package name )
intent.action = " You can give it to the server service Define a action"
intent.setPackage(" Server package name ")
val bindServiceResult = bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
}
private fun addPerson() {
// When the client calls the server method , You need to catch the following exceptions :
//RemoteException abnormal :
//DeadObjectException abnormal : An exception will be thrown when the connection is interrupted ;
//SecurityException abnormal : Defined in client and server AIDL An exception is thrown when a conflict occurs ;
try {
val addPersonResult = remoteServer?.addPerson(Person(" galen "))
log(TAG, "addPerson result = $addPersonResult")
} catch (e: RemoteException) {
e.printStackTrace()
} catch (e: DeadObjectException) {
e.printStackTrace()
} catch (e: SecurityException) {
e.printStackTrace()
}
}
private fun getPerson() {
val personList = remoteServer?.personList
log(TAG, "person list $personList")
}
override fun onDestroy() {
super.onDestroy()
// Finally remember unbindService
unbindService(serviceConnection)
}
}
Be careful :
If targetSdk yes 30, Then it needs to be dealt with Android 11 Package visibility in Specific see : https://developer.android.com/about/versions/11/privacy/package-visibility
Two 、in,out,inout keyword
Define... Above AIDL At the interface , I used a keyword in, The key is actually orientation tag, It is used to point out the way of data flow . also 2 individual tag yes out and inout, All non basic parameters need an orientation tag To point out the flow of data , Orientation of basic parameters tag Default and can only be in.
in The method is to transfer data from the client to the server ,out No way.
out The method is to transfer data from the server to the client ,in No way.
No matter whether the server has modified the object data passed in the past , The object reference of the client will not change , What changes is only the data of the client , be perfectly logical and reasonable , Cross process is the way to serialize and deserialize data .
3、 ... and 、oneway keyword
take aidl Add... Before the method of the interface oneway Keyword, this method is called asynchronously , Does not block the calling thread , When the client side calls the method of the server side , If you don't need to know the return result , At this time, using asynchronous call can improve the execution efficiency of the client .
verification : I will aidl Interface methods are defined as oneway Of , On the server AIDL Method implementation Thread.sleep(2000) Block the method call , Then the client calls this method , Check the time before and after the method call
private fun addPersonOneway() {
log(TAG, “oneway Starting time : ${System.currentTimeMillis()}”)
remoteServer?.addPersonOneway(Person(“oneway”))
log(TAG, “oneway End time : ${System.currentTimeMillis()}”)
}
// Log output
//oneway Starting time : 1608858291371
//oneway End time : 1608858291372
You can see , When the client calls this method, it is true that it is not blocked .
Four 、 Thread safety
AIDL The method is on the server side Binder Executed in thread pool , Therefore, when multiple clients connect and operate data at the same time, multiple threads may access at the same time . In this case , We need to be on the server side AIDL Method to deal with multi-threaded synchronization .
边栏推荐
猜你喜欢
随机推荐
在技术升级中迎合消费者需求,安吉尔净水器“价值战”的竞争之道
微信小程序,连续播放多段视频。合成一个视频的样子,自定义视频进度条
上半年暂停考试要补考?包含监理工程师、建筑师等十项考试
AirServer2022最新版功能介绍及下载
杰理之、产线装配环节【篇】
深度学习 常见的损失函数
如果浏览器被意外关闭,react怎么缓存用户填写的表单?
杰理之、产线装配环节【篇】
人才近悦远来,望城区夯实“强省会”智力底座
浏览器tab页之间的通信
PHP 读取ini或env类型配置
升级版手机检测微信工具小程序源码-支持多种流量主模式
王者战力查询改名工具箱小程序源码-带流量主激励广告
Pytest Collection (2) - mode de fonctionnement pytest
4. 对象映射 - Mapping.Mapstercover
MQ学习笔记
考虑关系的图卷积神经网络R-GCN的一些理解以及DGL官方代码的一些讲解
杰理之关于长按开机检测抬起问题【篇】
同花顺股票开户选哪个券商好手机开户是安全么?
函数基本学习之一









