我写这篇文章不想从最基础的介绍开始,我直接上步骤吧.
1.创建服务端
1.1:创建服务端项目:我的as版本比较高,页面就是这样的
1.2:创建AIDL文件,右键项目,选中aidl
aidl名字可以自定义也可以默认
basicTypes是自带的,可以删掉,也可以不删,然后把你自己所需的接口写上去
1.3:创建aidl调用的service:
1.4:根据aidl生成java文件供service调用:点击Rebuild Project等待完成
这个就是生成的java文件
1.5:编辑service,实现aidl的接口:如果没有生成java的话,会找不到IReceiverAidl
package com.howfor.receiver
import android.app.Service
import android.content.Intent
import android.graphics.Bitmap
import android.os.IBinder
import android.util.Log
class MyService : Service() {
var catBinder = object: IReceiverAidl.Stub() {
override fun basicTypes(
anInt: Int,
aLong: Long,
aBoolean: Boolean,
aFloat: Float,
aDouble: Double,
aString: String?
) {
Log.e("TAG","basicTypessetTime===========anInt")
}
override fun setTime(time: Long) {
Log.e("TAG","setTime===========$time")
}
override fun reboot() {
Log.e("TAG","reboot===========")
adwApi!!.Reboot()
}
override fun shutdown() {
Log.e("TAG","shutdown===========")
adwApi!!.ShutDown()
}
override fun install(fullPath: String?) {
Log.e("TAG","install===========$fullPath")
}
override fun beat(aBoolean: Boolean) {
Log.e("TAG","beat===========$aBoolean")
}
override fun setPower(power: MutableList<String>?) {
Log.e("TAG","setPower===========${power!!.size}")
}
override fun updateFirmware(localFile: String?) {
Log.e("TAG","updateFirmware===========${localFile}")
}
override fun getDeviceId(): String {
Log.e("TAG","getDeviceId===========")
return ""
}
override fun getName(): Array<String> {
Log.e("TAG","getName()===========")
val arrayEmpty = emptyArray<String>()
return arrayEmpty
}
override fun getPath(): Array<String> {
Log.e("TAG","getPath()===========")
val arrayEmpty = emptyArray<String>()
return arrayEmpty
}
override fun shouldClean(path: String?): Boolean {
Log.e("TAG","shouldClean()===========")
return true
}
override fun getBitmap(): Bitmap {
Log.e("TAG","getBitmap()===========")
var bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888)
return bitmap
}
override fun getVersion(): String {
Log.e("TAG","getVersion()===========")
return ""
}
}
override fun onBind(intent: Intent): IBinder {
return catBinder
}
}
1.6:设置service的属性:name会在客户端绑定使用到,所以我们会先自定义一个,不需要跟着你的Myservice一样
<service
android:name=".MyService"
android:exported="true">
<intent-filter>
<action android:name="com.howfor.receiver.service.ReceiverService" />
</intent-filter>
</service>
2.客户端使用:
2.1:创建客户端项目
2.2:复制服务端的aidl到客户端中:必须一模一样的,建议直接复制粘贴
2.3:生成java文件,与服务端1.4一样的步骤:
2.4:使用aidl并且绑定服务端的service:这里的com.howfor.receiver.service.ReceiverService就是1.6设置的属性,包名就是服务端的包名:
package com.example.aidlkhute
import android.annotation.SuppressLint
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
import android.os.IBinder
import android.os.RemoteException
import android.util.Log
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import com.howfor.receiver.IReceiverAidl
class MainActivity : AppCompatActivity() {
var mIReceiverAidl: IReceiverAidl? = null
var mConnections = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
Log.e("TAG", "onServiceConnected")
//注释3:
mIReceiverAidl = IReceiverAidl.Stub.asInterface(service)
}
override fun onServiceDisconnected(name: ComponentName?) {
Log.e("TAG", "onServiceDisconnected")
mIReceiverAidl = null
}
}
@SuppressLint("MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val intent = Intent()
intent.setPackage("com.howfor.receiver")
intent.action = "com.howfor.receiver.service.ReceiverService"
try {
var se = bindService(intent, mConnections, Context.BIND_AUTO_CREATE)
Log.e("TAG", "se=========$se")
} catch (e: RemoteException) {
Log.e("TAG", "e=========${e.message}")
}
}
override fun onDestroy() {
super.onDestroy()
unbindService(mConnections)
}
}
添加两个按钮使用里面的接口
findViewById<Button>(R.id.test).setOnClickListener {
if (mIReceiverAidl != null) {
try {
mIReceiverAidl!!.reboot()
} catch (e: RemoteException) {
Log.e("TAG", "e=========${e.message}")
}
} else {
Log.e("TAG", "mIReceiverAidl====null")
}
}
findViewById<Button>(R.id.test1).setOnClickListener {
if (mIReceiverAidl != null) {
try {
mIReceiverAidl!!.shutdown()
} catch (e: RemoteException) {
Log.e("TAG", "e=========${e.message}")
}
} else {
Log.e("TAG", "mIReceiverAidl====null")
}
}
先运行服务端,可以不用做任何操作,然后再运行客户端,点击对应的接口,就会打印出对应的log:
se=========true //代表服务绑定成功
reboot=========== //点击第一个按钮打印
shutdown=========== //点击第二个按钮打印
还有个小问题:在高版本(targetSdk 33)上会出现绑定失败的情况,然后查看了一下,在安卓11以上,google对系统做了一些操作,具体的可以自行百度:解决方案,在客户端添加红框中的内容即可