什么情况下会导致ANR,如何避免.
ANRs (“Application Not Responding”),意思是”应用没有响应“。
在如下情况下,Android会报出ANR错误:
-
主线程 (“事件处理线程” / “UI线程”) 在5秒内没有响应输入事件
-
BroadcastReceiver 没有在10秒内完成返回
通常情况下,下面这些做法会导致ANR
1、在主线程内进行网络操作
2、在主线程内进行一些缓慢的磁盘操作(例如执行没有优化过的SQL查询)
应用应该在5秒或者10秒内响应,否则用户会觉得“这个应用很垃圾”“烂”“慢”…等等
逻辑应该是
- new出一个新的线程,进行数据请求
- 获取数据后,调用handler.sendMessage方法
- 在handler的handle()方法中更新UI
关于getView方法中ViewHolder类static修饰符
viewholder是用来减少findview的次数,优化效力,这个确实可以减少
静态内部类主要作用就是,内部类是否需要隔离“外部类的this对象(指针)”。内部类是有 this 指针的,可以“直接”访问外部类的 成员变量和成员函数(包括私有的成员)。而静态内部类,没有这个this指针,所以无法“直接”调用。
ViewHolder的构造和复用,与静不静态没关。核心是ListView(AdapterView),通过getView(int position, View convertView, ViewGroup parent) 的convertView会为开发者传入一个可以复用的对象。开发者需要利用该对象,减少应用内存的消耗。
static的真正目是:
从减少内存消耗的角度来看。ViewHolder还是应该修饰成static比较好。这样ViewHolder中可以减少Activity的this指针,由于减少了一个this指针的引用,也会对Activity的引用计数大大减少。Activity的this指针继承于android的Context上下文,对于Context的回收遗漏,是Android内存管理中很大的问题。我们减少了对Context的引用,可以更容易减少Context引用计数出现问题。
Android之内存泄漏以及解决办法
内存泄漏和内存溢出的区别:
- 内存泄漏:在程序中动态分配给对象内存空间,当此对象所在的程序结束之后,此对象所占用的内存并没有被释放,那么就造成内存泄漏了。
- 内存溢出:就是系统分配一个10大小的内存空间给一个对象,但是这个对象实际需要20的空间来存放,那么这就造成了内存溢出。
- 内存泄露导致堆栈内存不断增大,从而引发内存溢出,内存泄漏时内存溢出的引发原因之一
单例造成的内存泄漏
单例模式的好处主要是提供一个实例,统一访问变量,不会造成过多的资源消耗。但是在Android开发中,我们经常会因为错误的使用单例模式而造成内存泄漏。
例如,实例化单例模式的时候,我们经常要传入一个context,如果单例的生命周期比我们的context生命周期更长,那么当我们的context需要释放时(context通常是activity),就会因为单例实例引用着context,因为这是强引用,导致context不能被及时回收,从而造成内存泄漏。
解决方法:
既然是实例的生命周期可能比传入的context生命周期要长,那么我们可以根据context获得有更长的生命周期的对象,比如application对象的生命周期是和APP的生命周期一样长的,就和传入的context进行了解耦
this.mContext = context.getApplicationContext();
Handler造成的内存泄漏
handler内部会持有Activity引用,Activity在finish()时得不到释放,资源无法及时回收,从而造成内存泄漏。
解决办法
在Activity结束的时候,移除mHandler的引用
mHandler.removeCallbacksAndMessages(null);
耗时线程造成的内存泄漏
解决办法
关闭activity时,stop线程
WebView引起的内存泄漏
WebView会在解析网页时,占用很多的内存。如果打开了十多个HTML页面,因为之前的页面不会被释放,用于快速返回前一个页面,所以占用内存就很很可能会爆,导致APP闪退。
解决办法 :
在我们推出承载WebView的activity之前,需要清除掉HTML页面占用的内存,释放资源
private void destroyWebView() {
if (mWebView != null) {
mLinearLayout.removeView(mWebView);
mWebView.pauseTimers();
mWebView.removeAllViews();
mWebView.destroy();
mWebView = null;
}
}
资源未关闭造成的内存泄漏
访问本地数据库的时候,为了不经常启动和关闭数据库,会保持一段时间对数据库的联系,但是我们在最后绝对不要忘了要及时关闭数据库
网友评论