RecyclerView+Glide加载大量图片,卡顿解决!

最近在做相册,但是发现当手机图片过多时,直接卡到ANR,这个问题困扰了我很久。

我怀疑了Glide缓存的问题。设置了Glide的缓存,内存等。

也怀疑了是一次性读取图片过多的问题。为此我做了读取分页加载,一次加载30张图片。但是当我图片加载到了300+的时候,又开始卡顿了。

这时我看到了我的xml里是用的:NestedScrollView+RecyclerView

我把RecyclerView单独拿出来,不用NestedScrollView进行包裹。这个时候,加载3000+图片,丝滑无比!

如果有和我一样用NestedScrollView+RecyclerView来做大量图片加载的同学,你尝试将RecyclerView单独拿出进行加载。

至于这其中的缘由,等我空了再进行分析,先做个避坑记录。

分页加载代码:

//监听RecyclerView滑动到底部,触发加载
//loadAllMediaData2(page);
    //loadSourceFolder();
    /*RecyclerView mView= mAlbumAllView.getAlbumRecyclerView();
    mView.addOnScrollListener(new RecyclerView.OnScrollListener() {
      @Override
      public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        if (newState == SCROLL_STATE_IDLE) {
          if (!mView.canScrollVertically(1)) { // 到达底部
            page += 1;
            loadAllMediaData2(page);
          } else if (!mView.canScrollVertically(-1)) { // 到达顶部
          }
        }
      }

      @Override
      public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
      }
    });*/

异步读取相片

/**
   * 分页加载读取
   */
  int page=1;
  @SuppressLint("CheckResult")
  private void loadAllMediaData2(int page){
    int pagesize = 30;
    List<AbstractBaseLocalFile> videoList = new ArrayList<>();
    Observable.just("")
            .subscribeOn(Schedulers.io())
            .map(new Function<String, List<AbstractBaseLocalFile>>() {
              @Override
              public List<AbstractBaseLocalFile> apply(@NonNull String s)  {
                Cursor mCursor = null;
                Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                String[] proj = {
                        MediaStore.Images.ImageColumns._ID,
                        MediaStore.Images.ImageColumns.DISPLAY_NAME,
                        MediaStore.Images.ImageColumns.DATA,
                        MediaStore.Images.ImageColumns.DATE_MODIFIED,
                        MediaStore.Images.ImageColumns.DATE_TAKEN,
                        MediaStore.Images.ImageColumns.SIZE,
                        MediaStore.Images.ImageColumns.MIME_TYPE
                };
                mCursor =
                        mContext
                                .getContentResolver()
                                .query(
                                        mImageUri,
                                        proj,
                                        MediaStore.Images.Media.MIME_TYPE
                                                + "=? or "
                                                + MediaStore.Images.Media.MIME_TYPE
                                                + "=? or "
                                                + MediaStore.Images.Media.MIME_TYPE
                                                + "=?",
                                        new String[] {"image/jpeg", "image/png", "image/jpg"},
                                        null);
                if (mCursor != null) {
                  int position = (page - 1) * pagesize + 1;
                  //int position = (mCursor.getCount() - 1) / pagesize + 1;
                  mCursor.moveToPosition(position);
                  Log.i("tang","page ======"+page);
                  Log.i("tang","position1 ======"+position);
                  Log.i("tang","count ======"+mCursor.getCount());
                  while (mCursor.moveToNext()) {
                    long modifiedData = mCursor.getLong(mCursor.getColumnIndex(MediaStore.Images.Media.DATE_MODIFIED));
                    int imgId = mCursor.getInt(mCursor.getColumnIndex(MediaStore.Images.Media._ID));
                    String path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.Media.DATA));
                    long size = mCursor.getLong(mCursor.getColumnIndex(MediaStore.Images.Media.SIZE)) / 1024;
                    long data = mCursor.getLong(mCursor.getColumnIndex(MediaStore.Images.ImageColumns.DATE_TAKEN));
                    //          String mimiType =
                    // mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.ImageColumns.MIME_TYPE));
                    if (size < 0) {
                      // 某些设备获取size<0,直接计算
                      size = new File(path).length();
                    }

                    // 获取该视频的父路径名
                    File file = new File(path);
                    if (!file.exists()) {
                      continue;
                    }
                    File parentFile = file.getParentFile();
                    if (parentFile == null || !parentFile.exists()) {
                      continue;
                    }
                    String dirPath = parentFile.getAbsolutePath();
                    LocalImageInfo itemBean = new LocalImageInfo();
                    itemBean.setId(imgId);
                    itemBean.setPath(path);
                    itemBean.setParentPath(dirPath);
                    itemBean.setSize(size);
                    MediaFile.MediaFileType fileType = MediaFile.getFileType(path);
                    if (fileType != null) {
                      itemBean.setMimeType(fileType.mimeType);
                    }

                    if (modifiedData == 0) {
                      itemBean.setModifyDate(data);
                    } else {
                      itemBean.setModifyDate(modifiedData);
                    }
                    videoList.add(itemBean);
                    if (page == 1 && mCursor.getPosition() == pagesize){
                      break;
                    }
                    if (mCursor.getPosition() >= pagesize * page){
                      break;
                    }
                    Log.i("tang","position2 ======"+mCursor.getPosition());

                  }
                }
                sortMediaDate(videoList);
                return videoList;
              }
            })
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<List<AbstractBaseLocalFile>>() {
              @Override
              public void accept(List<AbstractBaseLocalFile> list) {
                mAlbumAllView.showAlbumRecyclerView();
                // 只有图片类型,不存在多种Type
                if (mAlbumType == 0) {
                  updateAlbumAdapter(mDataList, mAlbumAllAdapter, TYPE_IMG);
                }

              }
            }, new Consumer<Throwable>() {
              @Override
              public void accept(Throwable throwable) {

              }
            });
  }


版权声明:本文为sweet_smile5原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。