前言
有些時候,我們需要在某些Activity中監聽某些狀態。當然不可能在每個Activity中創建一個實例去查詢和綁定吧。這時候,就需要一個統一管理狀態的框架,下面就以藍牙狀態監聽爲例,描述如何開發一個監聽框架。
文件架構
代碼
監聽者註解
創建文件 RDBluetoothObserver ,註解類,用於描述監聽者的方法
/**
* 藍牙狀態觀察者註解
*
* @author D10NG
* @date on 2019-11-12 09:25
*/
@kotlin.annotation.Target(AnnotationTarget.FUNCTION)
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
annotation class RDBluetoothObserver
狀態值枚舉類
創建文件 RDBluetoothStatus
/**
* 藍牙開關狀態
*
* @author D10NG
* @date on 2019-11-12 09:27
*/
enum class RDBluetoothStatus(val msg: String) {
NONE(msg = "當前設備不支持藍牙BLE"),
STATE_TURNING_ON(msg = "正在打開藍牙"),
STATE_ON(msg = "藍牙已打開"),
STATE_TURNING_OFF(msg = "正在關閉藍牙"),
STATE_OFF(msg = "藍牙已關閉"),
CONNECTED(msg = "藍牙已連接"),
DISCONNECTED(msg = "藍牙已斷開連接")
}
編寫接口
創建文件 IBluetoothCallBack
/**
* 藍牙狀態接口
*
* @author D10NG
* @date on 2019-11-12 09:30
*/
interface IBluetoothCallBack {
/**
* 註冊
* @param obj
*/
fun register(obj: Any)
/**
* 取消註冊
* @param obj
*/
fun unRegister(obj: Any)
/**
* 取消註冊
*/
fun unRegisterAll()
/**
* 打開藍牙
*/
fun openBluetooth()
/**
* 關閉藍牙
*/
fun closeBluetooth()
/**
* 獲取藍牙狀態
* @return
*/
fun getBluetoothStatus() : RDBluetoothStatus
}
業務邏輯
創建文件 BluetoothCallBack
/**
* 藍牙狀態監聽
*
* @author D10NG
* @date on 2019-11-12 09:31
*/
class BluetoothCallBack constructor(
application: Application
) : IBluetoothCallBack {
// 觀察者,key=類、value=方法
private val checkManMap = HashMap<Any, Method>()
@Volatile
private var bluetoothStatus: RDBluetoothStatus
private val bluetoothReceiver = BluetoothReceiver()
init {
// 初始化廣播
val intentFilter = IntentFilter()
// 監視藍牙關閉和打開的狀態
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED)
intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED)
intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED)
// 開始監聽
application.registerReceiver(bluetoothReceiver, intentFilter)
// 初始化藍牙狀態
val bleManager = application.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
val adapter = bleManager.adapter
bluetoothStatus = when {
adapter == null -> RDBluetoothStatus.NONE
adapter.isEnabled -> RDBluetoothStatus.STATE_ON
else -> RDBluetoothStatus.STATE_OFF
}
}
override fun register(obj: Any) {
val clz = obj.javaClass
if (!checkManMap.containsKey(clz)) {
val method = AnnotationUtils.findAnnotationMethod(
clz, RDBluetoothObserver::class.java,
RDBluetoothStatus::class.java) ?: return
checkManMap[obj] = method
}
}
override fun unRegister(obj: Any) {
checkManMap.remove(obj)
}
override fun unRegisterAll() {
checkManMap.clear()
}
override fun openBluetooth() {
val ble = BluetoothAdapter.getDefaultAdapter()
ble?.enable()
}
override fun closeBluetooth() {
val ble = BluetoothAdapter.getDefaultAdapter()
ble?.disable()
}
override fun getBluetoothStatus(): RDBluetoothStatus = bluetoothStatus
// 執行
private fun post(status: RDBluetoothStatus) {
bluetoothStatus = status
val set: Set<Any> = checkManMap.keys
for (obj in set) {
val method = checkManMap[obj] ?: continue
method.invoke(obj, status)
}
}
inner class BluetoothReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val action = intent?.action ?: return
when (action) {
BluetoothAdapter.ACTION_STATE_CHANGED -> {
when(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0)) {
BluetoothAdapter.STATE_TURNING_ON -> post(RDBluetoothStatus.STATE_TURNING_ON)
BluetoothAdapter.STATE_ON -> post(RDBluetoothStatus.STATE_ON)
BluetoothAdapter.STATE_TURNING_OFF -> post(RDBluetoothStatus.STATE_TURNING_OFF)
BluetoothAdapter.STATE_OFF -> post(RDBluetoothStatus.STATE_OFF)
}
}
BluetoothDevice.ACTION_ACL_CONNECTED -> {
post(RDBluetoothStatus.CONNECTED)
}
BluetoothDevice.ACTION_ACL_DISCONNECTED -> {
post(RDBluetoothStatus.DISCONNECTED)
}
}
}
}
}
暴露接口 單例
創建文件 RDBluetoothManager
/**
* 藍牙管理器
*
* @author D10NG
* @date on 2019-11-12 09:24
*/
class RDBluetoothManager constructor(
application: Application
) : IBluetoothCallBack {
private val bluetoothCallBack : IBluetoothCallBack
companion object {
@Volatile
private var INSTANCE : RDBluetoothManager? = null
@JvmStatic
fun getInstance(application: Application) : RDBluetoothManager {
val temp = INSTANCE
if (null != temp) {
return temp
}
synchronized(this) {
val instance = RDBluetoothManager(application)
INSTANCE = instance
return instance
}
}
}
init {
bluetoothCallBack = BluetoothCallBack(application)
}
override fun register(obj: Any) {
bluetoothCallBack.register(obj)
}
override fun unRegister(obj: Any) {
bluetoothCallBack.unRegister(obj)
}
override fun unRegisterAll() {
bluetoothCallBack.unRegisterAll()
}
override fun openBluetooth() {
bluetoothCallBack.openBluetooth()
}
override fun closeBluetooth() {
bluetoothCallBack.closeBluetooth()
}
override fun getBluetoothStatus(): RDBluetoothStatus = bluetoothCallBack.getBluetoothStatus()
}
混淆封裝
如果你想打包成第三方庫的話,看我的另一篇文章:
Android 簡單開發sdk教程一 接口寫法和混淆規則