You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin中编写统一处理SecurityException的通用函数

实现通用SecurityException捕获函数的方案

针对你需要统一处理不同类、不同返回值方法的SecurityException需求,用Kotlin的高阶函数就能轻松实现通用包装逻辑,彻底减少代码冗余。

基础版:极简通用捕获函数

这个版本能快速包装任意方法,捕获SecurityException并返回nullable结果,同时统一处理异常:

fun <T> safeBleOperation(block: () -> T): T? {
    return try {
        block()
    } catch (e: SecurityException) {
        // 这里写统一的异常处理逻辑:比如打日志、埋点、全局提示
        e.printStackTrace()
        // 示例:全局Toast提示权限问题(需传入Context可调整)
        // Toast.makeText(appContext, "蓝牙权限不足,请检查权限设置", Toast.LENGTH_SHORT).show()
        null
    }
}

使用示例

不管是返回布尔值的discoverServices(),还是返回Unit的disable(),都能直接用:

// 处理带返回值的方法
val discoverResult = safeBleOperation { bluetoothGatt?.discoverServices() }
discoverResult?.let {
    // 发现服务成功的逻辑
}

// 处理无返回值的方法
safeBleOperation { bluetoothAdapter?.disable() }

进阶版:支持自定义错误处理

如果不同场景需要不同的异常提示,可扩展函数加入自定义错误处理lambda:

fun <T> safeBleOperation(
    onSecurityError: (SecurityException) -> Unit = { it.printStackTrace() },
    block: () -> T
): T? {
    return try {
        block()
    } catch (e: SecurityException) {
        onSecurityError(e)
        null
    }
}

使用示例

在调用时指定当前场景的错误处理:

safeBleOperation(
    onSecurityError = {
        Toast.makeText(this, "关闭蓝牙需要权限,请授权后重试", Toast.LENGTH_SHORT).show()
    }
) {
    bluetoothAdapter?.disable()
}

进阶增强:区分"原方法返回null"和"异常捕获"

如果需要明确区分「方法本身返回null(比如bluetoothGatt为空)」和「触发SecurityException」两种情况,可以用密封类包装结果:

sealed class BleOperationResult<out T> {
    data class Success<out T>(val data: T) : BleOperationResult<T>()
    data class SecurityFailure(val exception: SecurityException) : BleOperationResult<Nothing>()
    object NullTarget : BleOperationResult<Nothing>() // 标记原方法因对象为空返回null
}

fun <T> safeBleOperation(block: () -> T?): BleOperationResult<T> {
    return try {
        val result = block()
        result?.let { BleOperationResult.Success(it) } ?: BleOperationResult.NullTarget
    } catch (e: SecurityException) {
        BleOperationResult.SecurityFailure(e)
    }
}

使用示例

通过when表达式清晰处理每种情况:

when (val result = safeBleOperation { bluetoothGatt?.discoverServices() }) {
    is BleOperationResult.Success -> {
        // 处理服务发现成功的逻辑
    }
    is BleOperationResult.SecurityFailure -> {
        Toast.makeText(this, "权限错误:${result.exception.message}", Toast.LENGTH_SHORT).show()
    }
    BleOperationResult.NullTarget -> {
        // 处理bluetoothGatt为空的逻辑,比如提示设备已断开
    }
}

补充提醒

虽然通用捕获能兜底异常,但提前做权限检查仍是更优方案:在调用蓝牙操作前,先判断权限是否授予(比如Manifest.permission.BLUETOOTH_ADMIN、Manifest.permission.BLUETOOTH_SCAN等),配合通用捕获实现双重保障,既减少异常触发,又避免崩溃。

内容的提问来源于stack exchange,提问作者kat opp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 03:45:32