在项目上线,遇到了一个让人很难受的问题,主界面滑动卡顿,有的手机情况情况还好,但是部分手机很糟糕,这个问题说实话让人很蛋疼。
RecyclerView相比较listview与gridview具有更多的活动性。所以在这个界面我使用万能刷新控件XRefreshView来包裹RecyclerView,item各有不同,第一个banner、第二个跑马灯效果、第三个gridview、第四个View、第五个view、后面的效果就是列表效果啦。
这种卡顿很多情况都是事件冲突所引起的,我的这个上面banner、跑马灯、gridview这些都可能存在滑动冲突,然后我把这些item一个个注释掉,但是效果并没有变好,这样说明我没有找到问题。
我用的图片加载框架是Fresco(3级缓存设计,合理运用好了设备本身的内存区域,图片管理过程非常高效,使得前端体验更加流畅,也较有效地避免了常见内存问题的产生。),他只加载当前展示区域的图片,在系统不足时,自己会去回收那些没有使用的内存。
在怀着不信的态度去尝试,是不是图片加载的消耗内存。注释这行代码后,果然成功了。0.0(很尴尬的找了那么久,测试环境图片分辨率都很小,正式环境图片分辨率达到了4000*3000换算下来加载一张图片内存需要消耗近30多M)
这里我相信大家知道了,是什么原因造成我界面的卡顿。图片加载消耗太多的内存,这样的情况轻者造成卡顿(我这个界面暂时只有几条数据),加载过多就会出现oom。
说了这么多,应该大家也知道怎么处理了。但是我还是要记录下来,万一我自己忘记了呢^-^。
解决这个最好的办法就是将服务器返回给我们的图片转换成bitmao进行压缩。
但是呢!哼哼,我不需要,因为Fresco提供了一个图片压缩的方法,具体如下:
public class ImageUtils {
private static Context mContext;
public ImageUtils(Context mContext) {
this.mContext = mContext;
}
public static void setImg(SimpleDraweeView mImg, String url) {
Uri uri = Uri.parse(url);
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
.setResizeOptions(new ResizeOptions(dp2px(140), dp2px(90)))
.build();
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setOldController(mImg.getController())
.setControllerListener(new BaseControllerListener
.setImageRequest(request).build();
mImg.setController(controller);
}
static int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, mContext.getResources()
.getDisplayMetrics());
}
}
事实证明只是比开始好一点点,经过查找还有这些优化方式:
RecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { if (newState == RecyclerView.SCROLL_STATE_IDLE) { }else { } } })
RecyclerView.SCROLL_STATE_IDLE //空闲状态
RecyclerView.SCROLL_STATE_FLING //滚动状态
RecyclerView.SCROLL_STATE_TOUCH_SCROLL //触摸后状态
Glide记载图片:
if (newState == RecyclerView.SCROLL_STATE_IDLE) { Glide.with(mContext).resumeRequests(); }else { Glide.with(mContext).pauseRequests(); }
Fresco加载图片:
if (newState == RecyclerView.SCROLL_STATE_IDLE) { Fresco.getImagePipeline().resume(); }else { Fresco.getImagePipeline().pause(); }
RecyclerView滑动事件监听加载--------------点击这里