前言
在Android
开发中,策略模式是一种常用的设计模式,它能够让我们在运行时动态选择算法或行为。本文将重点介绍如何在Android
中安全地实现策略模式,避免内存泄漏问题。
传统策略模式的问题
// ❌ 存在内存泄漏风险的实现
object LazyStart : StartStrategy {
override operator fun invoke(block: suspend () -> Unit) {
GlobalScope.launch {
delay(1000)
// 延迟执行可能导致内存泄漏,block表达式持有的Activity/Fragment可能销毁后再执行,导致Activity/Fragment无法被GC
block()
}
}
}
// 危险使用场景
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
LazyStart {
updateUI() // Activity可能已销毁,但lambda仍被执行
}
}
}
✅ 内存安全的解决方案
方案1:Class
实现 + 作用域绑定
class SafeImmediateStart(private val scope: CoroutineScope) : StartStrategy {
override operator fun invoke(block: suspend () -> Unit) {
scope.launch {
block()
}
}
}
class SafeLazyStart(private val scope: CoroutineScope) : StartStrategy {
override operator fun invoke(block: suspend () -> Unit) {
scope.launch {
delay(1000)
block()
}
}
}
// 安全使用
class MainActivity : AppCompatActivity() {
private val immediateStrategy = SafeImmediateStart(lifecycleScope)
private val lazyStrategy = SafeLazyStart(lifecycleScope)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
immediateStrategy {
updateUI() // 安全:Activity销毁时协程自动取消
}
}
}
方案2:枚举实现 + 作用域绑定
enum class SafeStartStrategy {
IMMEDIATE {
override fun execute(scope: CoroutineScope, block: suspend () -> Unit) {
scope.launch { block() }
}
},
LAZY {
override fun execute(scope: CoroutineScope, block: suspend () -> Unit) {
scope.launch {
delay(1000)
block()
}
}
};
abstract fun execute(scope: CoroutineScope, block: suspend () -> Unit)
operator fun invoke(scope: CoroutineScope, block: suspend () -> Unit) {
execute(scope, block)
}
}
// 使用方式
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
SafeStartStrategy.LAZY(lifecycleScope) {
updateUI()
}
}
}
实际应用场景
// 内存安全检查清单
class MemorySafeStrategy(
private val scope: CoroutineScope // ✅ 1. 绑定正确作用域
) : StartStrategy {
override operator fun invoke(block: suspend () -> Unit) {
scope.launch { // ✅ 2. 使用传入的scope
try {
block()
} catch (e: CancellationException) {
// ✅ 3. 处理取消异常
Log.d("Strategy", "Execution cancelled")
}
}
}
}
核心总结
场景 | 推荐方案 | 原因 |
---|---|---|
UI操作 | Class + lifecycleScope | 绑定Activity生命周期 |
数据处理 | Class + viewModelScope | 绑定ViewModel生命周期 |
简单工具 | 改进枚举 + scope参数 | 简洁且安全 |