引用类型概述
Java 提供了四种引用类型(从强到弱):
- 强引用 (Strong Reference)
- 软引用 (Soft Reference)
- 弱引用 (Weak Reference)
- 虚引用 (Phantom Reference)
1. 软引用 (SoftReference)
软引用是一种相对强引用弱化了一些的引用,主要用于内存敏感的缓存。
特点:
- 当内存不足时,软引用对象可能被回收
- 内存充足时,软引用对象不会被回收
- 适合用来实现内存敏感的缓存
示例代码:
class ImageCache {
private val cache = mutableMapOf<String, SoftReference<Bitmap>>()
fun putBitmap(key: String, bitmap: Bitmap) {
cache[key] = SoftReference(bitmap)
}
fun getBitmap(key: String): Bitmap? {
val softReference = cache[key]
return softReference?.get()
}
}
实际应用场景:
- 图片缓存
class ImageLoader {
private val memoryCache = mutableMapOf<String, SoftReference<Bitmap>>()
fun loadImage(url: String, imageView: ImageView) {
// 先从缓存中查找
val cachedBitmap = memoryCache[url]?.get()
if (cachedBitmap != null) {
imageView.setImageBitmap(cachedBitmap)
return
}
// 异步加载图片
coroutineScope.launch {
val bitmap = downloadImage(url)
memoryCache[url] = SoftReference(bitmap)
imageView.setImageBitmap(bitmap)
}
}
}
2. 弱引用 (WeakReference)
弱引用比软引用更弱,只要垃圾回收器运行,若只有弱引用指向该对象,就会被回收。
特点:
- 生命周期更短
- 下一次 GC 时一定会被回收
- 适合用来防止内存泄漏
示例代码:
class MyHandler(activity: Activity) {
private val activityRef: WeakReference<Activity> = WeakReference(activity)
fun handleMessage(msg: Message) {
val activity = activityRef.get()
activity?.let {
// 使用 activity 进行操作
}
}
}
实际应用场景:
- Handler 防止内存泄漏:
class MainActivity : AppCompatActivity() {
private val myHandler = object : Handler(Looper.getMainLooper()) {
private val weakReference = WeakReference(this@MainActivity)
override fun handleMessage(msg: Message) {
val activity = weakReference.get() ?: return
// 处理消息
}
}
}
- 观察者模式中防止内存泄漏:
class EventManager {
private val listeners = mutableListOf<WeakReference<EventListener>>()
fun addListener(listener: EventListener) {
listeners.add(WeakReference(listener))
}
fun notifyListeners() {
listeners.removeAll { it.get() == null } // 清理已被回收的引用
listeners.forEach {
it.get()?.onEvent()
}
}
}
- Fragment 引用:
class MyFragment : Fragment() {
private var callback: WeakReference<Callback>? = null
fun setCallback(callback: Callback) {
this.callback = WeakReference(callback)
}
private fun onSomeEvent() {
callback?.get()?.onCallback()
}
}
实践建议
-
缓存策略选择
- 对于内存敏感的缓存,使用 SoftReference
- 需要及时释放的对象引用,使用 WeakReference
-
防止内存泄漏
// 在 Activity 中使用异步任务 class LongRunningTask(activity: Activity) { private val activityRef = WeakReference(activity) fun execute() { GlobalScope.launch { // 长时间操作 withContext(Dispatchers.Main) { activityRef.get()?.updateUI() } } } } -
生命周期管理
class ViewModel { private var view: WeakReference<View>? = null fun attachView(view: View) { this.view = WeakReference(view) } fun detachView() { view = null } }
注意事项
-
及时清理
- 定期清理无效的弱引用
- 使用 WeakHashMap 等集合类自动处理弱引用
-
合理使用
- 不要过度使用弱引用
- 某些场景直接使用强引用更合适
-
性能考虑
- 频繁创建和销毁引用对象可能影响性能
- 合理设计缓存策略
-
引用队列
val referenceQueue = ReferenceQueue<Activity>() val weakReference = WeakReference(activity, referenceQueue) // 处理被回收的引用 val polled = referenceQueue.poll()
通过合理使用软引用和弱引用,可以有效地管理内存,防止内存泄漏,实现更健壮的 Android 应用程序。