在Android开发中,资源释放是确保应用性能和稳定性的关键环节,处理不当可能导致内存泄漏、性能下降甚至崩溃。以下是需要重点关注的资源和实践方法:
1. Bitmap资源释放
问题:Bitmap占用大量内存,未释放会引发OOM(Out Of Memory)。
解决方法:
- 使用`Bitmap.recycle()`手动回收(API 10以下必须调用)。
- 通过`BitmapFactory.Options.inBitmap`复用内存(减少GC频率)。
- 结合`SoftReference/WeakReference`缓存图片(需注意Android 2.3+的GC策略变化)。
2. Cursor与数据库连接
问题:未关闭Cursor会导致数据库连接泄漏,表现为`CursorWindow`内存增长。
最佳实践:
- 使用`try-finally`或`try-with-resources`(API 24+)确保关闭:
java
try (Cursor cursor = db.query(...)) {
// 操作cursor
}
- 避免在Activity中直接管理Cursor,推荐使用`Loader`或`Room`等ORM框架。
3. 文件流与IO操作
关键点:`FileInputStream`/`FileOutputStream`等必须显式关闭。
扩展知识:
- Java 7+的`AutoCloseable`接口可简化资源管理。
- 使用Okio等库可降低手动释放遗漏风险。
4. 绘图资源(Drawable)
注意事项:
- View销毁时需调用`Drawable.setCallback(null)`断开引用链(尤其对动画Drawable)。
- 自定义Drawable需覆写`onDetachedFromWindow()`释放内部资源。
5. WebView内存泄漏
解决方案:
- 独立进程+`WebView.destroy()`彻底释放(需处理进程通信)。
- 移除父View前调用`WebView.removeAllViews()`。
6. Handler与延时任务
隐患:Handler持有Activity引用导致无法回收。
优化方案:
- 使用静态Handler+WeakReference。
- 在`onDestroy()`中调用`handler.removeCallbacksAndMessages(null)`。
7. 动画资源(Animator)
释放时机:
- 在Activity生命周期结束时调用`Animator.cancel()`。
- 属性动画需注意无限重复动画的停止条件。
8. 广播与服务绑定
规范操作:
- 动态广播必须在`onDestroy()`中`unregisterReceiver()`。
- Service绑定需配对`bindService()`与`unbindService()`。
9. 线程与AsyncTask
风险控制:
- 后台线程持有Context引用需用`getApplicationContext()`。
- Android 11后推荐改用`ExecutorService`或协程(Kotlin)。
10. 工具与检测手段
辅助工具:
- LeakCanary检测内存泄漏。
- Android Profiler监控内存实时分配。
- StrictMode捕捉未关闭资源问题(开发阶段启用)。
11. 架构设计建议
采用Lifecycle组件自动管理资源(如`ViewModel`+`LiveData`)。
对复杂资源封装`CloseGuard`模式(参考`java.io.Closeable`实现)。
总结:Android资源释放需结合具体场景,区分Java原生资源(如流)与Android特有组件(如WebView)。现中,Jetpack组件和静态代码分析工具可显著降低泄露风险,但手动释放关键资源的意识仍不可或缺。