Android相册解决加载大量图片卡顿问题
来源:互联网 发布:车载网络硬盘录像机 编辑:程序博客网 时间:2024/04/30 13:28
Android开发中加载相册是很常用的功能,但相册图片过多正常加载会产生卡顿,即便使用线程异步加载图片卡顿问题依然得不到改善。
正常代码:
public class AlbumAdapter extends ?{ @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { if(bitmap!=null){ 线程加载图片 } else 读取缓存 }}
卡顿原因是无论怎样优化读取IO都是费时的工作,adapter又会一次实例多个子项,导致加载的图片过多,内存占用率过高产生了卡顿。
优化代码:
public class AlbumActivity extends AppCompatActivity{ private RecyclerView mRecyclerView; private List<PhotoItem> photoItemList; private List<PhotoItem> selectItemList; private int[] photoLayout; private AlbumAdapter mAdapter; private Handler handler; private Button submit; private GridLayoutManager gridLayoutManager; private static final String[] STORE_IMAGES = { MediaStore.Images.Media.DISPLAY_NAME, // 显示的名字 MediaStore.Images.Media.LATITUDE, // 维度 MediaStore.Images.Media.LONGITUDE, // 经度 MediaStore.Images.Media._ID, // id MediaStore.Images.Media.BUCKET_ID, // dir id 目录 MediaStore.Images.Media.BUCKET_DISPLAY_NAME, // dir name 目录名字 MediaStore.Images.Media.DATA//路径 }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_album); submit = (Button)findViewById(R.id.submit); mRecyclerView = (RecyclerView)findViewById(R.id.list); gridLayoutManager = new GridLayoutManager(this, 3); mRecyclerView.setLayoutManager(gridLayoutManager); mRecyclerView.setHasFixedSize(true); photoLayout = new int[2]; photoLayout[0]=(ScreenHelper.getScreenWidth(this) - ScreenHelper.dp2px(this, 20)) / 3 - ScreenHelper.dp2px(this, 10); photoLayout[1] = ScreenHelper.dp2px(this, 110); gridLayoutManager.findFirstCompletelyVisibleItemPosition(); initPhoto(); notifySubmit(); mAdapter = new AlbumAdapter(mRecyclerView,photoItemList,selectItemList); mAdapter.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(RecyclerView.ViewHolder viewHolder, int position) { notifySubmit(); } }); mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { //停止滑动后缓存当前屏幕图片 if(newState == 0){ new Thread(new Runnable() { @Override public void run() { for(int i=gridLayoutManager.findFirstVisibleItemPosition();i<gridLayoutManager.findLastVisibleItemPosition();i++){ cacheBitmap(i); } } }).start(); } } }); mRecyclerView.setAdapter(mAdapter); handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { mAdapter.notifyImage((int)msg.obj); return false; } }); } private void initPhoto(){ photoItemList = new ArrayList<>(); selectItemList = (List<PhotoItem>)getIntent().getSerializableExtra(FinalHelper.IMAGE_PATH); if(selectItemList == null) selectItemList = new ArrayList<>(); String path=""; for(int i=0;i<selectItemList.size();i++){ path += selectItemList.get(i).getPath()+","; } Cursor cursor = MediaStore.Images.Media.query(getContentResolver(), MediaStore.Images.Media.EXTERNAL_CONTENT_URI, STORE_IMAGES,"width >0","date_modified desc"); cursor.moveToNext(); for (int i = 0; i < cursor.getCount(); i++) { PhotoItem photoItem = new PhotoItem(cursor.getInt(3),path.indexOf(cursor.getString(6))!=-1?true:false,cursor.getString(0),cursor.getString(6)); photoItemList.add(photoItem); cursor.moveToNext(); } //从前往后存缓存缩略图 单线程轮播减少内存消耗确保屏幕不卡顿 new Thread(new Runnable() { @Override public void run() { for(int i=0;i<photoItemList.size();i++){ cacheBitmap(i); } } }).start(); } //缓存bitmap public void cacheBitmap(int position){ if(CacheManager.get(photoItemList.get(position).getPath())==null){ Bitmap bitmap = ImageHelper.getSmallCropBitmap(photoItemList.get(position).getPath(), photoLayout[0], photoLayout[1]); CacheManager.put(photoItemList.get(position).getPath(),bitmap); Message message = new Message(); message.obj=position; handler.sendMessage(message); } } public void notifySubmit(){ if(selectItemList.size()>0){ submit.setBackgroundResource(R.drawable.bg_album_submit_enable); submit.setText(getString(R.string.submit) + "(" + selectItemList.size() + ")"); submit.setTextColor(ContextCompat.getColor(this, R.color.white)); submit.setAlpha(1f); submit.setClickable(true); } else { submit.setBackgroundResource(R.drawable.bg_album_submit); submit.setTextColor(ContextCompat.getColor(this, R.color.darkgray)); submit.setAlpha(.8f); submit.setText(getString(R.string.submit)); submit.setClickable(false); } } public void onSubmit(View view){ Intent intent = new Intent(); intent.putExtra(FinalHelper.IMAGE_PATH, (Serializable) selectItemList); setResult(Activity.RESULT_OK, intent); finish(); } public void onBack(View view){ finish(); } public void onCancel(View view){ finish(); }}
在读取相册的基本数据后,采用单线程轮播的方式顺序缓存图片缩率图,这样便解决了卡顿问题,在配合缓存类,再次加载相册就可以瞬间全部加载完毕,推荐使用开源的第三方库DiskLruCache实现图片的缩略图缓存。
QQ相册初次加载相册图片也是一张一张的,仿QQ相册实例:http://blog.csdn.net/lishengko/article/details/56495553
0 0
- Android相册解决加载大量图片卡顿问题
- Android Listview 加载图片优化--本地加载大量图片,解决滑动卡顿现象(滑动停止加载图片)
- Android Listview 加载图片优化--本地加载大量图片,解决滑动卡顿现象(滑动停止加载图片)
- 使用LRUCACHE解决加载本地大量图片卡顿及OOM问题
- RunLoop优化加载大量图片的卡顿问题
- android 解决ViewPager加载大量图片内存溢出问题
- Viewpager加载大量图片的时候卡顿
- 安卓Viewpager加载大量图片的时候卡顿
- tableview 加载图片卡顿问题
- 解决MATE桌面图标加载卡顿问题
- Android 加载大量图片
- Android解决GridView异步加载大量图片时出现Out Of Memory问题00M
- 弱引用的场景——解决android gridView加载大量图片的性能问题
- ListView卡顿优化过程,并解决与viewpager图片加载冲突的问题
- Android完美解决GridView异步加载图片和加载大量图片时出现Out Of Memory问题
- Android完美解决GridView异步加载图片和加载大量图片时出现Out Of Memory问题
- Android解决GridView异步加载图片和加载大量图片时出现Out Of Memory问题--recycleBitmapCaches
- GridView加载大量图片卡的问题
- 数位dp
- 类模板的静态成员
- Android《第一行代码》第1~3章 笔记
- css----标记选择器,写入方法
- C++11学习
- Android相册解决加载大量图片卡顿问题
- Gstreamer的简单理解(转载)
- Category详解
- socket实现TCP通信
- 1.10:对象创建和生命期
- LeetCode-167. Two Sum II
- 读书笔记 effective c++ Item 15 在资源管理类中提供对原生(raw)资源的访问
- windows10 双屏幕扩展后,窗口拖动方向的问题。
- iOS UIslider 设定滑块的大小