Android 使用LeakCanary 检测内存泄露
2017-05-24 14:10
375 查看
转自:http://blog.csdn.NET/sbsujjbcy/article/details/47999163
LeakCanary 是 Android 和 Java 内存泄露检测框架,该框架是Square公司的一个开源库,项目地址 leakcanary。
Android 开发中你是否频频遇到内存泄露而无奈无从解决。说不定哪天你不小心写的一行代码就导致了内存泄露。可以先看看这些问题导致的内存泄露 Android开发编码规范导致的内存泄露问题,而LeakCanary 则很直白得检测出了内存泄露并展示给我们。在使用它之前,我们来写一个例子。
本地广播,在开发中还是有一定的应用的,现在有这么一个需求,要求使用本地广播来实现,就是通过发送一个退出程序的本地广播,所有Activity接收到后就退出,这显然是需要一个基础的Activity,其他Activity继承它。为了方便,这里我们只使用一个Activity。
[java] view
plain copy
public class MainActivity extends AppCompatActivity {
public final static String ACTION_EXIT_APP = "cn.edu.zafu.leakcanary.exit";
private static LocalBroadcastManager mLocalBroadcatManager;
private BroadcastReceiver mExitReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ACTION_EXIT_APP)) {
Log.d("TAG", "exit from broadcast");
finish();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_EXIT_APP);
filter.addCategory(Intent.CATEGORY_DEFAULT);
getLocalBroadcastManager().registerReceiver(mExitReceiver, filter);
}
private LocalBroadcastManager getLocalBroadcastManager() {
if (mLocalBroadcatManager == null) {
mLocalBroadcatManager = LocalBroadcastManager.getInstance(this);
}
return mLocalBroadcatManager;
}
}
乍一看,是不是感觉写的很对啊,那你就不够细心了,这还是少量的代码,对于项目中日积月累的代码,内存泄露或许无处不在。我们使用LeakCanary 对我们的代码进行检测下,看看到底哪里发生了内存泄露,以及该如何解决。
使用方法也很简单,首先加入依赖
[java] view
plain copy
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
从依赖中也是可以看出猫腻的。
然后在我们程序的Applictaion中进行安装,当然,不要忘记在清单文件中注册该Application。
[java] view
plain copy
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
LeakCanary.install(this);
}
}
我说就这么简单你会信,好了,我们安装到手机上看看。安装完成后运行该软件,打开后退出该软件,这时候你发现桌面上多了一个Leaks的图标。
![](https://img-blog.csdn.net/20150826100351823)
打开它后通知栏会有一个通知,通知你发生了内存泄露
![](https://img-blog.csdn.net/20150826100401162)
然后在软件里你会看到内存泄露的跟踪信息。
![](https://img-blog.csdn.net/20150826100406934)
点击下方的delete可以删除此条信息。
仔细一看,原来是我们的mLocalBroadcatManager发生了泄露,注册本地广播的时候,传入了this,系统内部保持了这个引用,当我们退出Activity时,这个引用还是指向我们的Activity,导致Activity回收失败。那么怎么解决了,既然退出的时候还持有引用,那么我们取消注册这个广播这个引用不就没了吗,重写onDestroy方法,进行取消注册。
重新运行一下,咦,你发现内存不再泄露了。该软件里不再提示内存泄露的跟踪信息了。
![](https://img-blog.csdn.net/20150826100416595)
就是这么简单,如果想更进一步了解使用方法,比如检测Fragment有没有泄露。可以参考官方给的例子,并且内存泄露的跟踪信息也是可以上传到服务器的,更多内容,参考 leakcanary
源码下载
http://download.csdn.net/detail/sbsujjbcy/9048449
LeakCanary 是 Android 和 Java 内存泄露检测框架,该框架是Square公司的一个开源库,项目地址 leakcanary。
Android 开发中你是否频频遇到内存泄露而无奈无从解决。说不定哪天你不小心写的一行代码就导致了内存泄露。可以先看看这些问题导致的内存泄露 Android开发编码规范导致的内存泄露问题,而LeakCanary 则很直白得检测出了内存泄露并展示给我们。在使用它之前,我们来写一个例子。
本地广播,在开发中还是有一定的应用的,现在有这么一个需求,要求使用本地广播来实现,就是通过发送一个退出程序的本地广播,所有Activity接收到后就退出,这显然是需要一个基础的Activity,其他Activity继承它。为了方便,这里我们只使用一个Activity。
[java] view
plain copy
public class MainActivity extends AppCompatActivity {
public final static String ACTION_EXIT_APP = "cn.edu.zafu.leakcanary.exit";
private static LocalBroadcastManager mLocalBroadcatManager;
private BroadcastReceiver mExitReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ACTION_EXIT_APP)) {
Log.d("TAG", "exit from broadcast");
finish();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_EXIT_APP);
filter.addCategory(Intent.CATEGORY_DEFAULT);
getLocalBroadcastManager().registerReceiver(mExitReceiver, filter);
}
private LocalBroadcastManager getLocalBroadcastManager() {
if (mLocalBroadcatManager == null) {
mLocalBroadcatManager = LocalBroadcastManager.getInstance(this);
}
return mLocalBroadcatManager;
}
}
乍一看,是不是感觉写的很对啊,那你就不够细心了,这还是少量的代码,对于项目中日积月累的代码,内存泄露或许无处不在。我们使用LeakCanary 对我们的代码进行检测下,看看到底哪里发生了内存泄露,以及该如何解决。
使用方法也很简单,首先加入依赖
[java] view
plain copy
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
从依赖中也是可以看出猫腻的。
然后在我们程序的Applictaion中进行安装,当然,不要忘记在清单文件中注册该Application。
[java] view
plain copy
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
LeakCanary.install(this);
}
}
我说就这么简单你会信,好了,我们安装到手机上看看。安装完成后运行该软件,打开后退出该软件,这时候你发现桌面上多了一个Leaks的图标。
打开它后通知栏会有一个通知,通知你发生了内存泄露
然后在软件里你会看到内存泄露的跟踪信息。
点击下方的delete可以删除此条信息。
仔细一看,原来是我们的mLocalBroadcatManager发生了泄露,注册本地广播的时候,传入了this,系统内部保持了这个引用,当我们退出Activity时,这个引用还是指向我们的Activity,导致Activity回收失败。那么怎么解决了,既然退出的时候还持有引用,那么我们取消注册这个广播这个引用不就没了吗,重写onDestroy方法,进行取消注册。
<code class="hljs java has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onDestroy</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onDestroy(); getLocalBroadcastManager().unregisterReceiver(mExitReceiver); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>
重新运行一下,咦,你发现内存不再泄露了。该软件里不再提示内存泄露的跟踪信息了。
就是这么简单,如果想更进一步了解使用方法,比如检测Fragment有没有泄露。可以参考官方给的例子,并且内存泄露的跟踪信息也是可以上传到服务器的,更多内容,参考 leakcanary
源码下载
http://download.csdn.net/detail/sbsujjbcy/9048449
相关文章推荐
- android内存泄露检测工具--LeakCanary 中文使用说明
- Android 使用LeakCanary 检测内存泄露
- Android 使用LeakCanary 检测内存泄露
- Android 使用LeakCanary 检测内存泄露
- 使用LeakCanary检测内存泄露
- LeakCanary Android 和 Java 内存泄露检测
- 使用新版Android Studio检测内存泄露和性能
- Android内存泄露检测工具---LeakCanary的前世今生
- Android 内存泄露检测工具 LeakCanary
- [置顶] Android Studio 插件之内存泄露检测LeakCanary使用
- 使用开源项目LeakCanary检测应用的内存泄露
- android之内存泄漏检测和解决方法及LeakCanary使用
- 使用新版Android Studio检测内存泄露和性能
- 使用新版Android Studio检测内存泄露和性能
- LeakCanary (Android 检测内存泄漏工具的使用)
- 使用新版Android Studio检测内存泄露和性能
- Android 和 Java 内存泄露检测工具--LeakCanary
- LeakCanary Android 和 Java 内存泄露检测
- Android内存泄露检测工具---LeakCanary的前世今生
- Android 内存泄露检测工具 LeakCanary 的监控原理