先贴一下仓库的访问地址:https://github.com/xuetaotao/imagepicker,欢迎大家提意见使用和star
一、存储基本知识
先来看看存储区域划分:
image.png
其中,以下目录无需存储权限即可访问:
1、App自身的内部存储
2、App自身的自带外部存储-私有目录
剩下的都需要申请存储权限,Android 10.0前后对于存储作用域访问的区别就体现在如何访问剩余这些目录内的文件。
重点在自带外部存储之共享存储空间和其它目录
详见:Android 10、11 存储完全适配!(建议收藏)
二、组件库的使用
1、基本使用方法:
2、基本参数说明(更多见ImagePicker#Builder类):
3、基础操作类MediaUtils相关方法说明:
三、组件库的迭代优化过程
1、多版本的支持与适配
主要是 ContentValues 对于存储路径的版本适配, Uri获取方式的版本适配,以及不同版本一些操作和访问权限的问题。具体说明如下:
a. Android10.0以上版本通过ContentProvider保存共享存储空间的媒体文件时:
b.Android7.0以上Uri获取方式
c.易出错的一些关于操作和访问权限的问题
如,(1)Android10以上不能再通过 mkdirs() 创建外部存储下创建目录;
(2)Android10不能通过文件路径Path访问外部存储下的文件,Android11又恢复了通过文件路径访问媒体文件,但是如果这么适配的话,在Android11的机型上跑没问题,但是Android10的机型上跑就会崩溃,因而最后决定统一使用MediaStore的API借助Uri访问。
(3)其他的问题等,工具库适配测试中已解决,但是特别容易出错的暂时想不起来了略过。
2、处理ActivityResult API回调问题
借助一个Fragment和RxJava的PublishSubject操作符处理回调问题。 PublishSubject与普通的Subject不同,在订阅时并不立即触发订阅事件,而是允许我们在任意时刻手动调用onNext(),onError(),onCompleted来触发事件。
3、处理Android7.0以上文件Uri获取需要使用到FileProvider的authority问题
这里最开始的解决方式是通过让调用者传入authority 参数来实现的,后来通过在组件库内部定义了一个FileProvider解决了该问题。
authorities在这里并没有固定的要求,填写什么值都是可以的,但必须保证这个值在整个手机上是唯一的,所以通常会使用${applicationId}作为前缀,以防止和其他应用程序冲突
拓展:https://blog.csdn.net/guolin_blog/article/details/108026357
在ContentProvider中也是可以获取到Context的,它什么时候执行呢,看下这个流程图:可以看到,一个应用程序的执行顺序是这个样子的。首先调用Application的attachBaseContext()方法,然后调用ContentProvider的onCreate()方法,接下来调用Application的onCreate()方法。那么,假如在自己的库当中实现了上述的Provider,会发生什么情况呢?会发现initialize()这个接口可以省略了,因为在Provider当中这个接口会被自动调用,这样在进入Application的onCreate()方法时,其实已经初始化过了。缺点就是,ContentProvider会增加许多额外的耗时。Jetpack的App Startup可以解决这个问题,它可以将所有用于初始化的ContentProvider合并成一个,从而使App的启动速度变得更快。
4、代码的逻辑与优化
a.将拍照与选择相册逻辑合二为一,并在执行下一步流程之前确保上一步传过来的结果都做了相关的判空与错误处理,不把问题往下一步流。
b.(1)选择相册的Intent Action由 ACTION_PICK 更换为 ACTION_GET_CONTENT,解决Android11的小米机型版本返回resultCode!=RESULT_OK,而是0的问题;(2) 另外调用ACTION_GET_CONTENT选择最近照片时,返回uri直接去操作会出异常,需要先复制到APP外部私有目录再进行操作;(3)部分机型调用ACTION_GET_CONTENT选择最近照片时,会显示出缓存的缩略图,但是实际上图片已删除,所以操作前需要判断图片是否存在
c.图片的压缩优化,现在支持LuBan压缩和Android原生压缩(默认,同时进行尺寸和质量压缩,大部分图片经过尺寸压缩后可直接达到要求,速度较快,显示效果也不错,质量压缩方面侧重在保证图片显示质量的前提下进行压缩),优化改进后体验好很多
d.耗时和存储占用的优化。关于耗时的优化,主要做的是减少不需要的复制操作和优化压缩方法,并在子线程进行;关于存储占用的优化是进行完相关各种操作后,删除过程中产生的不必要的图片文件。