使用说明-单例模式.md 14 KB

能力层 SDK 使用说明(单例模式)

📋 为什么用单例?

  • 连接/服务是全局唯一的(BLE、Socket.IO、推送等)
  • 多个界面需要共享同一个连接状态
  • 避免重复连接、浪费资源

🎯 推荐使用方式(本项目)

方式1:直接获取单例(最简单,推荐)

所有能力层都使用 getInstance() 获取单例:

// BLE服务(第一次调用需要context,后续不需要)
val bleService = BLEServiceImpl.getInstance(this)  // 或 getInstance(context)

// Socket.IO服务(不需要context)
val socketService = SocketIOServiceImpl.getInstance()

// 推送服务(不需要context,但initialize方法需要)
val pushService = PushServiceImpl.getInstance()

// 二维码服务(不需要context,但scanQRCode方法需要Activity)
val qrCodeService = QRCodeServiceImpl.getInstance()

// 分享服务(不需要context,但share方法需要Activity)
val shareService = ShareServiceImpl.getInstance()

// NFC服务(不需要context,但initialize方法需要Activity)
val nfcService = NFCServiceImpl.getInstance()

说明

  • BLE服务:第一次调用getInstance(context)时需要context(用于获取BluetoothManager),后续调用可以不带context
  • 其他服务:getInstance()不需要context,但具体方法(如initialize、scanQRCode等)可能需要Activity

方式2:依赖注入(如果项目用了Dagger/Hilt)

@Module
@InstallIn(SingletonComponent::class)
object CapabilityModule {
    @Provides @Singleton
    fun provideBLEService(@ApplicationContext context: Context) = BLEServiceImpl.getInstance(context)
    
    @Provides @Singleton
    fun provideSocketIOService() = SocketIOServiceImpl.getInstance()
    
    @Provides @Singleton
    fun providePushService() = PushServiceImpl.getInstance()
}

// 在Activity中注入
@Inject lateinit var bleService: BLEService
@Inject lateinit var socketService: SocketIOService

📝 各能力层使用示例

1. BLE服务(capability-ble)

class VehicleControlActivity : AppCompatActivity() {
    private val bleService = BLEServiceImpl.getInstance(this)
    
    fun connectDevice(device: BLEDevice) {
        // 统一使用lambda回调
        bleService.connect(device) { response ->
            if (response.success) {
                // 连接成功
            } else {
                // 连接失败
                val error = response.errorMessage
            }
        }
    }
    
    fun lockCar() {
        bleService.sendAppControlCommand(
            AppControlInstruction.SET_DEFENSE,
            byteArrayOf(0x01)
        ) { response ->
            if (response.success) {
                // 设防成功
                val data = response.data  // ByteArray?
            } else {
                // 设防失败
                val error = response.errorMessage
            }
        }
    }
}

2. Socket.IO服务(capability-socketio)

class MessageActivity : AppCompatActivity() {
    private val socketService = SocketIOServiceImpl.getInstance()
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // 初始化并连接
        socketService.init("ws://server.com", token)
        socketService.connect()
        
        // 监听消息
        socketService.on("message") { response ->
            // 处理消息
        }
        
        // 发送消息
        socketService.emit("send_message", data)
    }
}

3. 推送服务(capability-push)

class MainActivity : AppCompatActivity() {
    private val pushService = PushServiceImpl.getInstance()
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // 初始化
        pushService.initialize(this)
        
        // 设置别名
        pushService.setAlias(userId)
        
        // 监听推送消息
        pushService.setMessageListener { message ->
            // 处理推送消息
        }
        
        // 注册推送
        pushService.register()
    }
}

4. 二维码服务(capability-qrcode)

class ScanActivity : AppCompatActivity() {
    private val qrCodeService = QRCodeServiceImpl.getInstance()
    
    fun scanQRCode() {
        qrCodeService.scanQRCode(this) { response ->
            if (response.success) {
                // 处理扫码结果(统一使用data字段)
                val content = response.data  // String?(二维码内容)
            } else {
                // 扫码失败
                val error = response.errorMessage
            }
        }
    }
    
    fun generateQRCode(content: String): Bitmap? {
        return qrCodeService.generateQRCode(content, 300)
    }
}

5. 分享服务(capability-share)

class ShareActivity : AppCompatActivity() {
    private val shareService = ShareServiceImpl.getInstance()
    
    fun shareToWeChat() {
        val content = ShareContent(
            title = "标题",
            description = "内容",
            imageUrl = "https://...",
            url = "https://..."
        )
        
        shareService.shareToWeChat(this, content) { response ->
            if (response.success) {
                // 分享成功(统一使用data字段)
                val platform = response.data  // SharePlatform?
            } else {
                // 分享失败
                val error = response.errorMessage
            }
        }
    }
}

6. NFC服务(capability-nfc)

class NFCActivity : AppCompatActivity() {
    private val nfcService = NFCServiceImpl.getInstance()
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // 初始化(需要Activity)
        nfcService.initialize(this)
        
        // 检查NFC支持
        if (nfcService.isNFCSupported()) {
            // 读取NFC标签
            nfcService.readTag { response ->
                if (response.success) {
                    // 处理NFC数据
                }
            }
        }
    }
}

✅ 使用要点

  1. 所有界面获取的都是同一个实例 ```kotlin // 界面1 val service1 = XxxServiceImpl.getInstance()

// 界面2 val service2 = XxxServiceImpl.getInstance()

// service1 和 service2 是同一个对象


2. **连接状态在所有界面共享**
   ```kotlin
   // 界面1:连接
   socketService.connect()
   
   // 界面2:直接使用(无需重新连接)
   if (socketService.isConnected()) {
       socketService.emit("event", data)
   }
  1. 不需要手动销毁
    • 单例在应用生命周期内一直存在
    • 不需要在Activity的onDestroy()中销毁
    • 需要断开连接时调用对应的disconnect()方法

📨 响应处理说明

1. BLE服务响应处理

BLE服务统一使用lambda回调处理响应:

// 连接响应(统一使用lambda)
bleService.connect(device) { response ->
    if (response.success) {
        // 连接成功
    } else {
        // 连接失败
        val error = response.errorMessage
    }
}

// 指令响应(统一使用lambda)
bleService.sendAppControlCommand(
    AppControlInstruction.SET_DEFENSE,
    byteArrayOf(0x01)
) { response ->
    if (response.success) {
        // 指令成功,response.data包含响应数据(ByteArray)
        val data = response.data
    } else {
        // 指令失败
        val error = response.errorMessage
    }
}

// 数据接收监听(实时数据)
bleService.setDataReceivedListener(object : DataCallback {
    override fun onDataReceived(data: ByteArray) {
        // 接收到实时数据(车辆状态、电池信息等)
        // 需要解析数据包
    }
})

响应数据格式(统一结构):

  • BLEResponse.success: 是否成功
  • BLEResponse.data: 响应数据(ByteArray?,需要根据协议解析)
  • BLEResponse.errorCode: 错误码(可选)
  • BLEResponse.errorMessage: 错误消息(可选)
  • BLEResponse.timestamp: 时间戳

2. Socket.IO服务响应处理

Socket.IO使用事件监听和回调处理响应:

// 监听事件(接收消息)
socketService.on("vehicle_status") { response ->
    // response.event: 事件名称
    // response.data: JSON字符串
    // response.timestamp: 时间戳
    
    val jsonData = JSONObject(response.data)
    // 解析数据
}

// 发送消息(不需要响应回调,单向发送)
socketService.emit("control_command", commandData)

// 如果需要响应,可以监听对应的事件
socketService.on("command_response") { response ->
    // 处理响应
}

响应数据格式

  • SocketIOResponse.event: 事件名称(String)
  • SocketIOResponse.data: 数据(JSON字符串)
  • SocketIOResponse.timestamp: 时间戳(Long)

3. 推送服务响应处理

推送服务使用监听器处理消息:

// 设置消息监听器
pushService.setMessageListener { message ->
    // message.title: 推送标题
    // message.content: 推送内容
    // message.extras: 额外数据(Map<String, String>)
    
    // 处理推送消息
    showNotification(message.title, message.content)
}

// 其他操作(setAlias、setTags等)通常不需要响应回调
pushService.setAlias(userId)
pushService.setTags(listOf("tag1", "tag2"))

响应数据格式

  • PushMessage.title: 推送标题
  • PushMessage.content: 推送内容
  • PushMessage.extras: 额外数据(Map)

4. 二维码服务响应处理

二维码服务使用回调处理响应(统一结构):

// 扫码响应
qrCodeService.scanQRCode(this) { response ->
    if (response.success) {
        // 扫码成功(统一使用data字段)
        val content = response.data  // String?(二维码内容)
    } else {
        // 扫码失败
        val error = response.errorMessage
    }
}

// 识别图片中的二维码
qrCodeService.recognizeQRCode(bitmap) { response ->
    if (response.success) {
        val content = response.data  // String?
    } else {
        val error = response.errorMessage
    }
}

响应数据格式(统一结构):

  • QRCodeResponse.success: 是否成功
  • QRCodeResponse.data: 二维码内容(String?)
  • QRCodeResponse.errorCode: 错误码(可选)
  • QRCodeResponse.errorMessage: 错误消息(可选)
  • QRCodeResponse.timestamp: 时间戳

5. 分享服务响应处理

分享服务使用回调处理响应(统一结构):

shareService.shareToWeChat(this, content) { response ->
    if (response.success) {
        // 分享成功(统一使用data字段)
        val platform = response.data  // SharePlatform?
        Toast.makeText(this, "分享成功", Toast.LENGTH_SHORT).show()
    } else {
        // 分享失败
        val error = response.errorMessage
        Toast.makeText(this, "分享失败: $error", Toast.LENGTH_SHORT).show()
    }
}

响应数据格式(统一结构):

  • ShareResponse.success: 是否成功
  • ShareResponse.data: 分享平台(SharePlatform?)
  • ShareResponse.errorCode: 错误码(可选)
  • ShareResponse.errorMessage: 错误消息(可选)
  • ShareResponse.timestamp: 时间戳

6. NFC服务响应处理

NFC服务使用回调处理响应(统一结构):

// 读取NFC标签
nfcService.readTag { response ->
    if (response.success) {
        // 读取成功(统一使用data字段)
        val data = response.data  // ByteArray?
    } else {
        // 读取失败
        val error = response.errorMessage
    }
}

// 写入NFC标签
nfcService.writeTag(data) { response ->
    if (response.success) {
        // 写入成功
    } else {
        val error = response.errorMessage
    }
}

// 设置标签发现监听器(实时监听)
nfcService.setTagDiscoveredListener { response ->
    // NFC标签靠近时触发
    if (response.success) {
        val data = response.data  // ByteArray?
    }
}

响应数据格式(统一结构):

  • NFCResponse.success: 是否成功
  • NFCResponse.data: 数据(ByteArray?)
  • NFCResponse.errorCode: 错误码(可选)
  • NFCResponse.errorMessage: 错误消息(可选)
  • NFCResponse.timestamp: 时间戳

⚠️ 注意事项

响应处理通用原则(统一模式)

  1. 统一响应结构:所有能力层(除Socket.IO)都使用相同的响应结构

    data class XxxResponse(
       val success: Boolean,
       val data: T? = null,              // 数据类型不同
       val errorCode: Int? = null,
       val errorMessage: String? = null,
       val timestamp: Long = System.currentTimeMillis()
    )
    
  2. 统一回调方式:所有能力层都使用lambda回调

    service.xxx(...) { response ->
       if (response.success) {
           val data = response.data
       } else {
           val error = response.errorMessage
       }
    }
    
  3. 异步回调:所有响应都是异步的,不要在主线程中阻塞等待

  4. 错误处理:始终检查success字段,处理失败情况

  5. 数据解析

    • BLE/NFC:响应数据是ByteArray?,需要根据协议文档解析
    • QRCode:响应数据是String?(二维码内容)
    • Share:响应数据是SharePlatform?(分享平台)
    • Socket.IO:响应数据是JSON字符串,需要解析
  6. 生命周期:注意在Activity/Fragment销毁时取消监听,避免内存泄漏

各服务特殊注意事项

  • BLE服务:传入的Context会自动转换为ApplicationContext,避免内存泄漏
  • Socket.IO服务:连接状态在所有界面共享,注意事件监听的注册和注销(使用off()方法)
  • 推送服务:通常在Application中初始化一次即可,消息监听器全局有效
  • NFC服务:需要Activity上下文,单例内部会管理当前Activity
  • 测试:可以调用XxxServiceImpl.destroyInstance()重置单例