Android性能优化之Activity 泄漏
2016-03-03 12:05
435 查看
随着移动互联网的发展,android
app开发越发火爆。大家都知道一个app的成功与否,与app的性能体验密不可分。如果一个app打开时间长、滑动不流畅等等,那么相信不管你的产品多么棒,运营多么牛叉,也不会获得用户的青睐。因此app的开发中,提升性能尤其重要。
当然,从事android开发的童鞋应该都知道app性能提升的重要性,但难点在于如何提升android app的性能、如何让用户体验更棒??下面小编就为大家分享一位来自谷歌专注于需要高性能的
App开发工程师,关于app性能优化之避免Activity 泄漏的解决方案。废话不多说,赶紧来get这个新技能吧~~
Activity 泄漏是怎么发生的?
在android app性能优化中,第一个需要修护的问题就是 Activity 泄漏那Activity 泄漏是怎么发生的,为什么会泄漏呢?Activity 泄漏是内存泄漏的一种,如果你持有一个未使用的
Activity 的引用,其实也就持有了 Activity 的布局,自然也就包含了所有的 View,最棘手的是持有静态引用。别忘了,Activity 和 Fragment 都有自己的生命周期。一旦我们持有了静态引用,Activity 和 Fragment 就不会被垃圾回收器清理掉了。这就是为什么静态引用很危险。
另外,泄漏 Listener 也是经常会发生的事情。比如说,我有下面的代码。 LeakActivity 继承自 Activity ,我们有一个单例: NastyManager ,当我们通过 addListener(this) 将 Activity 作为 Listener 和 NastyManager 绑定起来的时候,不好的事情就发生了。
想要修复这样的 Bug,其实相当简单,就是在你的 Acitivity 被销毁的时候,将他和 NastyManager 取消掉绑定就好了。
相对上面的解决方案,我们自然还有更好的。比如我们真的需要用到单例吗?通常,并不需要。不过某些时候可能真的很需要。我们得权衡和设计。不过无论如何,记住, 当 Activity 销毁的时候,在单例中移除掉对 Activity 的引用 。下面我们讨论下: 如果是内部类,会发生什么 ?比如说,我们有一个在 Activity 里有一个很简短的非静态 Handler。尽管它看起来很短,但是只要它还存活着,那么包含它的
Activity 就会存活着。如果你不信,可以在 VM 里试试看。这就是另一个内存泄漏的案例: Activity 内部的 Handler 。
Handler 是个很常用也很有用的类,异步,线程安全等等。如果有下面这样的代码,会发生什么呢? handler.postDeslayed ,假设 delay 时间是几个小时…
这意味着什么?意味着只要 handler 的消息还没有被处理结束,它就一直存活着,包含它的 Activity 就跟着活着。我们来想办法修复它,修复的方案是 WeakReference ,也就是所谓的弱引用。垃圾回收器在回收的时候,是会忽视掉弱引用的,所以包含它的 Activity 会被正常清理掉。大概代码如下:
概括来说:我们有个内部类,就像 Handler,内部非静态类是不能脱离所属类而单独存活的,Android 里通常是 Activity。所以,看看你的代码里的内部类,确保他们没有出现内存泄漏。
相比非静态内部类,最好使用静态内部类。区别就是静态内部类不依赖所属类,他们拥有不同的生命周期。我经常见到类似的原因引起的内存泄露。
如何避免 Activity 泄漏?
1、移除掉所有的静态引用。
2、考虑用 EventBus 来解耦 Listener。
3、记着在不需要的时候,解除 Listener 的绑定。
4、尽量用静态内部类。
5、做 Code Review。个人经验:Code Review 能很早的发现内存泄漏。
6、了解你程序的结构。
7、用类似 MAT,Eclipse Analyzer,LeakCanary 这样的工具分析内存。
8、在 Callback 里打印 Log。
以上就是android app性能优化中,Activity 泄漏的原因及解决办法,大家在开发app的时候,不妨可以通过上面的方法检测、解决或说避免Activity 泄漏吧。
相关文章:《Android
MVP开发模式的结构及优缺点详解》
文章来源:Realm CN
app开发越发火爆。大家都知道一个app的成功与否,与app的性能体验密不可分。如果一个app打开时间长、滑动不流畅等等,那么相信不管你的产品多么棒,运营多么牛叉,也不会获得用户的青睐。因此app的开发中,提升性能尤其重要。
当然,从事android开发的童鞋应该都知道app性能提升的重要性,但难点在于如何提升android app的性能、如何让用户体验更棒??下面小编就为大家分享一位来自谷歌专注于需要高性能的
App开发工程师,关于app性能优化之避免Activity 泄漏的解决方案。废话不多说,赶紧来get这个新技能吧~~
Activity 泄漏是怎么发生的?
在android app性能优化中,第一个需要修护的问题就是 Activity 泄漏那Activity 泄漏是怎么发生的,为什么会泄漏呢?Activity 泄漏是内存泄漏的一种,如果你持有一个未使用的
Activity 的引用,其实也就持有了 Activity 的布局,自然也就包含了所有的 View,最棘手的是持有静态引用。别忘了,Activity 和 Fragment 都有自己的生命周期。一旦我们持有了静态引用,Activity 和 Fragment 就不会被垃圾回收器清理掉了。这就是为什么静态引用很危险。
m_staticActivity = staticFragment.getActivity()
另外,泄漏 Listener 也是经常会发生的事情。比如说,我有下面的代码。 LeakActivity 继承自 Activity ,我们有一个单例: NastyManager ,当我们通过 addListener(this) 将 Activity 作为 Listener 和 NastyManager 绑定起来的时候,不好的事情就发生了。
public class LeakActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); NastyManager.getInstance().addListener(this); } }
想要修复这样的 Bug,其实相当简单,就是在你的 Acitivity 被销毁的时候,将他和 NastyManager 取消掉绑定就好了。
@Override public void onDestroy() { super.onDestroy(); NastyManager.getInstance().removeListener(this); }
相对上面的解决方案,我们自然还有更好的。比如我们真的需要用到单例吗?通常,并不需要。不过某些时候可能真的很需要。我们得权衡和设计。不过无论如何,记住, 当 Activity 销毁的时候,在单例中移除掉对 Activity 的引用 。下面我们讨论下: 如果是内部类,会发生什么 ?比如说,我们有一个在 Activity 里有一个很简短的非静态 Handler。尽管它看起来很短,但是只要它还存活着,那么包含它的
Activity 就会存活着。如果你不信,可以在 VM 里试试看。这就是另一个内存泄漏的案例: Activity 内部的 Handler 。
public class MainActivity extends Activity { //... Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //... handler = new Handler() { @Override public void handleMessage(Message msg) { } } }
Handler 是个很常用也很有用的类,异步,线程安全等等。如果有下面这样的代码,会发生什么呢? handler.postDeslayed ,假设 delay 时间是几个小时…
这意味着什么?意味着只要 handler 的消息还没有被处理结束,它就一直存活着,包含它的 Activity 就跟着活着。我们来想办法修复它,修复的方案是 WeakReference ,也就是所谓的弱引用。垃圾回收器在回收的时候,是会忽视掉弱引用的,所以包含它的 Activity 会被正常清理掉。大概代码如下:
private static class MyHandler extends Handler { private final WeakReference<MainActivity> mActivity; // ... public MyHandler(MainActivity activity) { mActivity = new WeakReference<MainActivity>(activity); //... } @Override public void handleMessage(Message msg) { } //... }
概括来说:我们有个内部类,就像 Handler,内部非静态类是不能脱离所属类而单独存活的,Android 里通常是 Activity。所以,看看你的代码里的内部类,确保他们没有出现内存泄漏。
相比非静态内部类,最好使用静态内部类。区别就是静态内部类不依赖所属类,他们拥有不同的生命周期。我经常见到类似的原因引起的内存泄露。
如何避免 Activity 泄漏?
1、移除掉所有的静态引用。
2、考虑用 EventBus 来解耦 Listener。
3、记着在不需要的时候,解除 Listener 的绑定。
4、尽量用静态内部类。
5、做 Code Review。个人经验:Code Review 能很早的发现内存泄漏。
6、了解你程序的结构。
7、用类似 MAT,Eclipse Analyzer,LeakCanary 这样的工具分析内存。
8、在 Callback 里打印 Log。
以上就是android app性能优化中,Activity 泄漏的原因及解决办法,大家在开发app的时候,不妨可以通过上面的方法检测、解决或说避免Activity 泄漏吧。
相关文章:《Android
MVP开发模式的结构及优缺点详解》
文章来源:Realm CN
相关文章推荐
- Android中如何让DialogFragment全屏(DialogFragment fullscreen)
- Android之带group指示器的ExpandableListView
- Android布局优化之Merge、Include、ViewStub使用与源码分析
- AndroidStudio和Git的那些事
- Android Activity的生命周期
- [Android 性能优化系列]布局篇之通过<include>复用布局
- Android gradle配置
- AndroidGPS获取当前经纬度坐标
- [Android 性能优化系列]布局篇之减少你的界面层级
- Android 颜色对照表
- 找不到类 android...app.WindowDecorActionBar
- [Android 性能优化系列]那些不能忽略的小细节
- Android Studio导入项目非常慢的解决办法
- [Android 性能优化系列]内存之终极篇--降低你的内存消耗
- 自己努力要学习啦(android的很多demo 总有你需要的)
- android 开发技巧(15)--为ListView添加分段标头
- Android Camera HAL V3 Vendor Tag及V1,V3参数转换
- Android 隐藏ViewPager之后,控件点击事件无法响应的问题
- [Android 性能优化系列]内存之提升篇--应用应该如何管理内存
- Android Studio :Error:(1, 0) Plugin is too old, please update to a more recent version, or set AND……