ImagePicker
ImagePicker copied to clipboard
compileSdkVersion 版本 27 及以上,大图返回列表时数据空了。
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. }
- while (data.moveToNext()) 为false, 导致ImageGridActivity页面展示变成了空。 这里没接触过, 不甚了解。
又测了一下, 发现是因为appcompat-v7 的问题, 如果改到26.1.0 则不会出现这个问题。。。
因为v7包27后LoaderManager加了lifecycle所以当Activity onResume的时候onLoadFinished会再回调一次。而这次cursor的数据已经移到最后一行了cursor.hasNext为false数据就清空了。在while前将cursor移动到第一行,就ok了。
if(!data.moveToFirst()){ return; }
楼上正解
这个问题,依赖库有修复。直接引用的还没更新。
这样写会有问题,直接导致每次从预览或者裁剪页面回来的时候,页面总是会初始化,而且不能更新到最新的图片(系统相册更新不到) 亲测,以下这段代码就可以了: 这里的打印的log,可以让你明白为什么这么搞 Timber.tag("onLoadFinished"); Timber.e("onLoadFinished State" + activity.getLifecycle().getCurrentState() + ",imageFolders" + imageFolders.size());
//这里的具体的代码,是根据上面哥们分析的原理,我试出来的解决方案,没毛病 if (activity.getLifecycle().getCurrentState() == STARTED && imageFolders.size() > 0){ return; }
照着楼上同学的思路打印了一下发现,activity.getLifecycle().getCurrentState()不仅仅会有STARTED一个状态,还会出现RESUMED状态 onLoadFinished State = RESUMED 所以上面的那个判断还是存在问题。
if ((activity.getLifecycle().getCurrentState() == STARTED || activity.getLifecycle().getCurrentState() == RESUMED) && imageFolders.size() > 0) { return; }
这样以后应该就没问题了
if ((activity.getLifecycle().getCurrentState() == STARTED || activity.getLifecycle().getCurrentState() == RESUMED) && imageFolders.size() > 0) {
return;
}
这句代码加在哪里,加在 imageFolders.clear(); 前面吗?
是的
@XuNeverMore 感动啊!!!! 终于解决了这个bug!!!!!
@dvzhou 请问这段代码是加在ImagePreviewActivity里还是ImageGridActivity里? 还是具体哪个类?我已经把前面两个activity本地化了,但都找不到你们说的那个方法.
ImageDataSource 这个类里
@flyjiang2014 十分感谢!
activity.getSupportLoaderManager().destroyLoader(loaderID); 直接在onloadfinish里面把loader取消了 省得多次重复调用onloadfinish 反正数据不会变
我用的Android studio 为什么改代码时候总提示file is readonly,解锁文件点了也不管用
这个问题我发现如果你的相册没有一张照片就会报错。 String imageName = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[0])); 这段代码。