1.Butterknife Zelezny
1.说明:
butterknife是一个专注于Android系统的View注入框架,使代码更加简洁。
2.支持特性
1.支持 Activity 中的 View 注入
2.支持 View 中的 View 注入
3.支持 View 事件回调函数注入
目前支持如下事件回调函数:
-
View: @OnLongClick and @OnFocusChanged.
-
TextView: @OnEditorAction.
-
AdapterView: @OnItemClick and @OnItemLongClick.
-
CompoundButton: @OnCheckedChanged
1.eclipse 中的使用 参考:http://jakewharton.github.io/butterknife/ide-eclipse.html
也可以参考博客:http://www.cnblogs.com/MonkeyAC/articles/4242312.html
2.android studio 中的使用
<1.as 中settings -->plugins->浏览器中搜索Butterknife zelezny 安装后重启as.
<2.build.gradle中 添加:
compile 'com.jakewharton:butterknife:6.1.0'
<3.在activity 中使用时 添加 ButterKnife.inject(this); 右击布局文件view ,选择generate,再选择generate butterknife injections ,最后点comfim 即可。
2.Gsonformat
1.说明:大多数服务端api都以json数据格式返回,而客户端需要根据api接口生成相应的实体类。
2.使用方法:as 插件中浏览器搜索gsonformat 下载后重启as.
在实体类中右键选择generate 选择gsonformat ,在输入框中复制json 字符串,点OK即可。
3.ParcelableGenerator
1.说明:Android中的序列化有两种方式,分别是实现Serializable接口和Parcelable接口,但在Android中是推荐使用Parcelable,只不过我们这种方式要比Serializable方式要繁琐,那么有了这个插件一切就ok了。
2.使用方法:
1.下载插件:地址:https://github.com/mcharmas/android-parcelable-intellij-plugin/releases/tag/v0.6.3
2.as settings ->pulgins 选择install pulgins from disk 安装重启即可。
3.选择一个实体类,右键选择generate->parcelable ,选中需要序列化的变量,点OK即可。
4.LeakCanary
1.说明:Square最近刚开源的一个非常有用的工具,强烈推荐,帮助你在开发阶段方便的检测出内存泄露的问题,使用起来更简单方便。
内存泄漏:当一个对象已经不需要再使用了,本该被回收时,而有另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这就产生了内存泄漏。
先来分析下内存泄漏的原因:
1.资源对象没关闭造成的内存泄漏。
2.构造Adapter时,没有使用缓存的convertView
3.Bitmap对象不在使用时调用recycle()释放内存
4.试着使用关于application的context来替代和activity相关的context
5.注册没取消造成的内存泄漏
6.集合中对象没清理造成的内存泄漏。
下面列举一个因为资源对象没关闭导致内存泄漏的例子,并用leakCanary检测出来。
单例模式非常受开发者的喜爱,不过使用的不恰当的话也会造成内存泄漏,由于单例的静态特性使得单例的生命周期和应用的生命周期一样长,这就说明了如果一个对象已经不需要使用了,而单例对象还持有该对象的引用,那么这个对象将不能被正常回收,这就导致了内存泄漏。如下这个典例:
public class TestModel { private static TestModel sInstance; private ImageView mView; private Context context; private TestModel(Context context){ this.context = context; } public static TestModel getInstance(Context context) { if (sInstance == null) { sInstance = new TestModel(context); } return sInstance; } public void setRetainedTextView(ImageView mView) { Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.lollipop); mView.setImageBitmap(bitmap); } }
这是一个普通的单例模式,当创建这个单例的时候,由于需要传入一个Context,所以这个Context的生命周期的长短至关重要:
1、传入的是Application的Context:这将没有任何问题,因为单例的生命周期和Application的一样长
2、传入的是Activity的Context:当这个Context所对应的Activity退出时,由于该Context和Activity的生命周期一样长(Activity间接继承于Context),所以当前Activity退出时它的内存并不会被回收,因为单例对象持有该Activity的引用。
所以正确的单例应该修改为下面这种方式:
public class TestModel { private static TestModel sInstance; private ImageView mView; private Context context; private TestModel(Context context){ this.context = context.getApplicationContext(); } public static TestModel getInstance(Context context) { if (sInstance == null) { sInstance = new TestModel(context); } return sInstance; } public void setRetainedTextView(ImageView mView) { Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.lollipop); mView.setImageBitmap(bitmap); } }
这样不管传入什么Context最终将使用Application的Context,而单例的生命周期和应用的一样长,这样就防止了内存泄漏。
回到问题的出发点,那我们要怎么才能检测出上面的内存泄漏情况呢,
1.首先as 中 gradle 中添加依赖
dependencies {
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
}
2.在 Application 中:
public class ExampleApplication extends Application {
@Override public void onCreate() {
super.onCreate();
LeakCanary.install(this);
}
}
如果检测到某个 activity 有内存泄露,LeakCanary 就是自动地显示一个通知。点击就可以查看具体哪些对象存在内存没有释放的情况。