好吧,今天就现学现卖,把今天刚学会用的新东西分析給大家。内存泄露自动探测神器——LeakCanary。它是一个Android和Java的内存泄露检测库,可以大幅度减少了开发中遇到的OOM问题,对于开发者来说,无疑是个福音,下面对该库的readme进行简单的翻译:
“A small leak will sink a great ship.” - Benjamin Franklin
小漏不补沉大船。——本杰明 富兰克林
什么是内存泄露(memory leak)?
一些对象有有限的使用期,当它们的工作完成后,它们预期会被当作内存垃圾回收。如果一个持有对象的引用链结束了它的预期寿命,这将会产生一个内存泄露。随着泄露的积累,应用程序将会耗尽内存。
例如,Activity的onDestroy()被调用后,这个Activity的视图层次和相关的位图都应该进行垃圾回收。而如果一个线程在后台运行这个Activity的引用,那么相应的内存将不能被回收,这最终就导致了OutOfMemoryError的出现。
(上述描述转载自:http://www.jianshu.com/p/e9891d7512ff)
接下来我们开始使用LeakCanary这个工具目前我只知道在Android Studio上可以使用,其他的我就没试过。
在我们做项目的初期阶段,对于OOM可能不会引起太多的关注,只想把项目能够按时完成,所以在我们开发的过程中难免会忽略内存的优化,特别是对于配置较低,或者图片Bitmap过大等情况是非常容易出现OOM的情况的。
首先,在项目的build.gradle文件添加:
//内存泄露检测工具 区分开发、发行版
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
初始化 内存检测工具
package com.fryp.frnewweb;
import android.app.Application;
import android.content.Context;
import com.squareup.leakcanary.LeakCanary;
import com.squareup.leakcanary.RefWatcher;
/**
* Created by Administrator on 2016/5/31.
*/
public class MyApplication extends Application {
private static MyApplication instance;
static Context mContext;
private RefWatcher refWatcher;
@Override
public void onCreate() {
super.onCreate();
mContext = getApplicationContext();
refWatcher = LeakCanary.install(this);//初始化 内存检测工具
}
/**
* 获取全局的Context
*/
public static Context getContextInstance() {
return mContext;
}
/**
* 获得内存监视器 监视任何对象
* 使用 refWatcher.watch(object);
*
* @return 全局的refWatcher
*/
public static RefWatcher getRefwatcher(Context context) {
MyApplication myApplication = (MyApplication) context.getApplicationContext();
return myApplication.refWatcher;
}
public static MyApplication getInstance() {
if (null == instance) {
instance = new MyApplication();
}
return instance;
}
}
到此,LeakCanary就可以监听所有的Activity的内存异常问题,并将问题在通知栏那里展示,点击就能够查看问题的详细了。如下图
上述只针对Activity的监听,当我们需要在Fragment监听异常时,需要在onDestroy的方法中,获取在MyApplication 中的全局变量refWatcher并开始监听。
package com.fryp.frnewweb.base;
import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.fryp.frnewweb.MyApplication;
import butterknife.ButterKnife;
public abstract class BaseFragment extends Fragment {
private View rootView;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(getLayoutId(), container, false);
return rootView;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onDetach() {
super.onDetach();
}
@Override
public void onDestroyView() {
super.onDestroyView();
}
@Override
public void onDestroy() {
super.onDestroy();
MyApplication.getRefwatcher(getActivity()).watch(this);
}
}
到这里为止,你就可以一直点击App中经常崩溃但不知道原因的地方,然后查看错误信息就行了。我在这里需要的功能不是很多,当然了这个工具具备的特点不止这些。你可以修改通知栏通标、上传错误信息到服务器,发布正式版本的时候使RefWatcher失效,不需要在客户端弹出通知等。那些详细的功能点在这里我就不一一描述了,不同的朋友可以去参照:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0510/2860.html