ImagePicker icon indicating copy to clipboard operation
ImagePicker copied to clipboard

compileSdkVersion 版本 27 及以上,大图返回列表时数据空了。

Open cxystyle opened this issue 6 years ago • 16 comments

compileSdkVersion 版本 27,appcompat-v7 27.1.0 出现的问题。

ImagePreviewActivity 返回到 ImageGridActivity 时, 会触发 ImageDataSource 的


1. public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
2.             imageFolders.clear();
3.             if (data != null) {
4.                  //所有图片的集合,不分文件夹
5.                 ArrayList<ImageItem> allImages = new ArrayList<>();   
6.                 while (data.moveToNext()) {
7. 
8.                     //查询数据
9.                     String imageName = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[0]));
10.                     String imagePath = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[1]));
11. 
12.                     File file = new File(imagePath);
13.                     if (!file.exists() || file.length() <= 0) {
14.                         continue;
15.                     }
16. 
17.                     long imageSize = data.getLong(data.getColumnIndexOrThrow(IMAGE_PROJECTION[2]));
18.                     int imageWidth = data.getInt(data.getColumnIndexOrThrow(IMAGE_PROJECTION[3]));
19.                     int imageHeight = data.getInt(data.getColumnIndexOrThrow(IMAGE_PROJECTION[4]));
20.                     String imageMimeType = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[5]));
21.                     long imageAddTime = data.getLong(data.getColumnIndexOrThrow(IMAGE_PROJECTION[6]));
22.                     //封装实体
23.                     ImageItem imageItem = new ImageItem();
24.                     imageItem.name = imageName;
25.                     imageItem.path = imagePath;
26.                     imageItem.size = imageSize;
27.                     imageItem.width = imageWidth;
28.                     imageItem.height = imageHeight;
29.                     imageItem.mimeType = imageMimeType;
30.                     imageItem.addTime = imageAddTime;
31.                     allImages.add(imageItem);
32.                     //根据父路径分类存放图片
33.                     File imageFile = new File(imagePath);
34.                     File imageParentFile = imageFile.getParentFile();
35.                     ImageFolder imageFolder = new ImageFolder();
36.                     imageFolder.name = imageParentFile.getName();
37.                     imageFolder.path = imageParentFile.getAbsolutePath();
38. 
39.                     if (!imageFolders.contains(imageFolder)) {
40.                         ArrayList<ImageItem> images = new ArrayList<>();
41.                         images.add(imageItem);
42.                         imageFolder.cover = imageItem;
43.                         imageFolder.images = images;
44.                         imageFolders.add(imageFolder);
45.                     } else {
46.                         imageFolders.get(imageFolders.indexOf(imageFolder)).images.add(imageItem);
47.                     }
48.                 }
49.                 //防止没有图片报异常
50.                 if (data.getCount() > 0 && allImages.size()>0) {
51.                     //构造所有图片的集合
52.                     ImageFolder allImagesFolder = new ImageFolder();
53.                     allImagesFolder.name = activity.getResources().getString(R.string.ip_all_images);
54.                     allImagesFolder.path = "/";
55.                     allImagesFolder.cover = allImages.get(0);
56.                     allImagesFolder.images = allImages;
57.                     imageFolders.add(0, allImagesFolder);  //确保第一条是所有图片
58.                 }
59.             }
60. 
61.             //回调接口,通知图片数据准备完成
62.             ImagePicker.getInstance().setImageFolders(imageFolders);
63.             loadedListener.onImagesLoaded(imageFolders);
64.         }

  1. while (data.moveToNext()) 为false, 导致ImageGridActivity页面展示变成了空。 这里没接触过, 不甚了解。

cxystyle avatar Apr 04 '18 02:04 cxystyle

又测了一下, 发现是因为appcompat-v7 的问题, 如果改到26.1.0 则不会出现这个问题。。。

cxystyle avatar Apr 04 '18 02:04 cxystyle

因为v7包27后LoaderManager加了lifecycle所以当Activity onResume的时候onLoadFinished会再回调一次。而这次cursor的数据已经移到最后一行了cursor.hasNext为false数据就清空了。在while前将cursor移动到第一行,就ok了。 if(!data.moveToFirst()){ return; }

XuNeverMore avatar Apr 11 '18 07:04 XuNeverMore

楼上正解

youarenowhere avatar May 18 '18 07:05 youarenowhere

这个问题,依赖库有修复。直接引用的还没更新。

WooYu avatar Jun 07 '18 11:06 WooYu

这样写会有问题,直接导致每次从预览或者裁剪页面回来的时候,页面总是会初始化,而且不能更新到最新的图片(系统相册更新不到) 亲测,以下这段代码就可以了: 这里的打印的log,可以让你明白为什么这么搞 Timber.tag("onLoadFinished"); Timber.e("onLoadFinished State" + activity.getLifecycle().getCurrentState() + ",imageFolders" + imageFolders.size());

//这里的具体的代码,是根据上面哥们分析的原理,我试出来的解决方案,没毛病 if (activity.getLifecycle().getCurrentState() == STARTED && imageFolders.size() > 0){ return; }

yq2yizi avatar Jun 20 '18 07:06 yq2yizi

照着楼上同学的思路打印了一下发现,activity.getLifecycle().getCurrentState()不仅仅会有STARTED一个状态,还会出现RESUMED状态 onLoadFinished State = RESUMED 所以上面的那个判断还是存在问题。

dvzhou avatar Jun 21 '18 02:06 dvzhou

if ((activity.getLifecycle().getCurrentState() == STARTED || activity.getLifecycle().getCurrentState() == RESUMED) && imageFolders.size() > 0) { return; }

这样以后应该就没问题了

dvzhou avatar Jun 21 '18 05:06 dvzhou

if ((activity.getLifecycle().getCurrentState() == STARTED || activity.getLifecycle().getCurrentState() == RESUMED) && imageFolders.size() > 0) { return; }
这句代码加在哪里,加在 imageFolders.clear(); 前面吗?

flyjiang2014 avatar Jun 26 '18 02:06 flyjiang2014

是的

dvzhou avatar Jun 26 '18 02:06 dvzhou

@XuNeverMore 感动啊!!!! 终于解决了这个bug!!!!!

BenjaminGao999 avatar Jun 29 '18 12:06 BenjaminGao999

@dvzhou 请问这段代码是加在ImagePreviewActivity里还是ImageGridActivity里? 还是具体哪个类?我已经把前面两个activity本地化了,但都找不到你们说的那个方法.

tempersitu avatar Jun 29 '18 13:06 tempersitu

ImageDataSource 这个类里

flyjiang2014 avatar Jun 29 '18 14:06 flyjiang2014

@flyjiang2014 十分感谢!

tempersitu avatar Jun 29 '18 14:06 tempersitu

activity.getSupportLoaderManager().destroyLoader(loaderID); 直接在onloadfinish里面把loader取消了 省得多次重复调用onloadfinish 反正数据不会变

taoqiyang avatar Jul 13 '18 06:07 taoqiyang

我用的Android studio 为什么改代码时候总提示file is readonly,解锁文件点了也不管用

lvshaohua avatar Aug 22 '18 02:08 lvshaohua

这个问题我发现如果你的相册没有一张照片就会报错。 String imageName = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[0])); 这段代码。

qq171161636 avatar Aug 16 '19 08:08 qq171161636