android文件上传优化分享(切片上传)

我重点看的是切片上传的原理。

原文链接:https://www.jianshu.com/p/b4c453649d92

========================================================

主题

记录安卓端上传模块优化的经历。通过本次分享,咱们可以知道

  1. 一个文件经历了几个步骤才能从手机上传到服务端
  2. 能知道媒体文件压缩的原理

整个优化经历了两个阶段

  1. 第一阶段是上传模块重构,并且通过UI和数据的分离,提升了扩展性,逐步被运用到产品的各个模块中
  2. 第二阶段是上传尺寸的优化,通过对视频文件的压缩,大幅减少用户的上传等待时间。

chapter 1.上传框架重构

评估现有模块表现

  1. 使用中低配置手机运行apk,查看上传模块实际表现
  2. 使用Charles抓包工具,观察每个上传文件体积是否被压缩到合理范围、对上传模块发送的http请求按照功能对其分类,检查是否可以合并同类请求
  3. 退出上传,查看上传后续步骤是否被停止;大文件重新上传是否跳过已上传的数据块
  4. 查看上传后的结果是否正常播放、是否失真、音频异常

上传模块现存问题

  • UI和上传代码耦合在一起,难以拓展维护
  • 停止上传后仍然继续上传,说明流程控制有问题
  • 在上传时,对每个文件会进行尺寸压缩、计算md5值,比较费时
  • 每个文件上传前都会发送一次存在校验(根据文件md5值),导致在上传的场景中会发送多次http请求校验文件存在
  • 视频文件没有做压缩,导致上传费时

整体设计思路

上传设计思路.png

  1. 数据UI分离:使用观察模式,抽离UI部分代码。使用弱引用设置观察者,避免生命周期不一致引起的内存泄漏。
  2. 费时操作前置:在选择图片的步骤,开启异步线程压缩图片、计算md5,将费时操作提前处理掉(此步骤在mx4 pro上处理拍照的图片耗时100~200ms,基本上选择图片后就已经完成好了计算)
  3. 将文件上传成功的md5值保存在内存中,避免重复处理。
  4. 分次请求合并:向服务端开发者申请批校验的接口,将多个文件存在的http请求被合并成一个。

优化后 逻辑UML

上传步骤.png

文件切片

文件切片将一个大文件切成若干小文件进行上传,在上传失败的情况下,可以跳过已上传的小文件。
切片代码底层使用JDK的RandomAccessFile对文件提供数据读取
经测试,上传的瓶颈在于上行带宽,所以切片、上传时单线程任务,不会出现10个切片一起上传的情况。
切片目前设定为10MB一片,上传时,把当前的块的数据读取到内存中进行上传

切片步骤

  1. 对文件md5计算,向服务端校验文件是否已存在,是则提前结束
  2. 对文件进行切片,计算每片的md5值用于校验是否已上传。比如38mb的视频,限定每片最大10mb,切出4片,最后一片8mb,其余10mb。
                    FileChannel fc = new RandomAccessFile(mSourceFile, "r").getChannel();
                    MappedByteBuffer byteBuffer;

                    for (int i = 0; i < mBlockCount; i++) {
                        long leftBlockSize = Math.min(mSourceFile.length() - i * mBlockSize, mBlockSize);
                        byteBuffer = fc.map(FileChannel.MapMode.READ_ONLY, i * mBlockSize, leftBlockSize).load();
                        mResultArray.add(new BlockInfoModel("", MD5Util.md5(byteBuffer), i));
                    }
                    fc.close();
  1. 批校验文件的切片md5值, 记录没有被上传过的切片下标,循环从源文件读取对应数据切片进行上传。切片数据流读到内存中性能最佳,但是需要谨慎考虑OOM问题;数据流保存到磁盘中,再循环每次1MB的读取比较稳健,但是性能稍差。本次重构提供了这两种切片方式都可以选择
  2. 所有数据切片上传成功后,向服务端发起一次文件合并请求,成功则结束,否则跳到步骤3。

chapter 2.媒体压缩

对于媒体资源来说,压缩就是在保证用户体验的情况下,尽可能地抹去用户感官之外的细节,达到降低文件尺寸的目的
1.音频的无损格式ape、flv 压缩到有损格式的Mp3,就是抹去了人听觉之外的音频细节
2.图片视频经过压缩,虽然放大N倍看细节会变得模糊,但是正常浏览下是可以接受的

举个例子
针对 1920*1080的屏幕截图,经过压缩后尺寸不变,但是降低采样率,文件体积从1MB降低到了200KB

 

图片压缩.png

 

压缩前.png

压缩后.png

图片压缩

压缩算法参考鲁班
通过等比例降低图片的采样率、分辨率、压缩质量等关键因素,大幅度减少输出的像素点数量,达到降低图片的体积的目的
在不影响浏览体验的前提下,能很大比例压缩图片体积

鲁班跑分.png

视频压缩

通过降低视频的分辨率、码率等关键因素,降低视频的体积。
压缩方案可选1:第三方so库FFmpeg软解 2:使用安卓原生MediaCodec 硬解
因为压缩效率、引入体积等问题,我们选择了MediaCodec方案
我们采用的压缩策略是分辨率450*800,码率是1.5M

视频压缩UML.png

在选择微信作为对比标杆的情况下,我们达到了这个标准

压缩结果.png

视频压缩UI

视频压缩1.png

视频上传1.png

总结

通过这两个阶段的重构,安卓端的上传模块初步形成了一个完整的体系,能够满足产品的使用需求,被广泛的应用到各个产品线的业务模块中。

备注

码率
码率是数据传输时单位时间传送的数据位数,一般我们用的单位是kbps即千位每秒。
通俗一点的理解就是取样率,单位时间内取样率越大,精度就越高,处理出来的文件就越接近原始文件
1920x1080分辨率的视频,码率应该在8Mb以上。
1080x720的分辨率,应该在5Mb左右
720x576分辨率,应该在3Mb左右
640x480分辨率,应该在1.5Mb左右
320x240的分辨率,应该在600Kb左右。



作者:雷霆之喜
链接:https://www.jianshu.com/p/b4c453649d92
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: element 文件切片上传是一种将大文件分割成小块进行上传的技术。它的实现原理是将文件分割成固定大小的块,然后逐个上传这些块,最后在服务器端将这些块重新组装成完整的文件。 element 文件切片上传具有以下几个优点: 1. 提高上传效率:将文件切片上传可以避免一次性传输大文件时遇到的网络传输问题,如带宽限制等。可以将文件分割成多个小块进行上传,大大提高了上传速度和效率。 2. 断点续传:由于文件被分割成小块,所以当传输过程中出现中断或错误时,只需要从出现中断或错误的位置重新上传即可,而不需要重新上传整个文件。这样可以极大地减少传输的时间和流量。 3. 更好的用户体验:通过文件切片上传,用户可以在上传过程中进行其他操作,如取消、暂停、继续等,这样可以提升用户的操作体验和灵活性。 实现element文件切片上传的基本步骤如下: 1. 客户端将文件分割成固定大小的块,并按照顺序逐个上传到服务器端。 2. 服务器端接收到每个块后,进行验证和存储。如果上传的块有误或者丢失,服务器端会通知客户端重新上传该块。 3. 客户端收到服务器端的通知后,重新上传出错的块,直到全部块上传完成。 4. 服务器端在接收到全部块后,将这些块按照顺序进行组装,还原成完整的文件。 5. 服务器端通知客户端上传完成,客户端可以进行后续操作,如展示上传结果或者其他处理。 总之,element 文件切片上传是一种高效、稳定和灵活的文件上传技术,可以提升文件上传的效率和用户体验。它的实现过程相对较为复杂,但通过合理的切片上传策略,可以有效地实现大文件的快速上传。 ### 回答2: 文件切片上传是指将大文件分割成多个小片段进行上传的一种技术。这种方法可以提高文件上传的效率,减少对网络带宽的压力,并且在上传过程中出现错误时也可以更容易地进行重传。 使用 element 进行文件切片上传的步骤如下: 1. 将待上传的文件进行分割。可以将文件拆分为大小相等的片段,通常每个片段大小在几十 KB 到几百 KB 之间。我们可以使用 JavaScript 的 File API 来实现这一步骤。 2. 为每个片段生成一个唯一的标识符,通常使用文件的名称加上片段的序号。这个标识符用于在后续的上传和合并过程中进行识别。 3. 将每个片段逐个上传到服务器。这可以通过发送 HTTP POST 请求来实现,请求中包含当前片段的标识符和数据。 4. 服务器收到每个片段后,将它们保存在临时存储位置,然后返回一个成功上传的响应。 5. 最后一步是将所有片段合并成完整的文件。当所有片段都上传完成后,可以向服务器发送一个合并请求,请求中包含所有片段的标识符和文件的元数据。服务器在收到请求后,将按照标识符的顺序将所有片段合并成完整的文件,并将保存在目标位置。 总结来说,element 文件切片上传是将大文件分割为多个小片段进行上传,提高上传效率和减少网络压力的方式。通过逐个上传每个片段,服务器在接收到所有片段后再进行合并操作,最终得到完整的文件。这种技术在大文件上传中被广泛应用,例如云存储服务或大型数据传输。 ### 回答3: Element文件切片上传是一种文件上传的方式。通常情况下,我们将文件上传到服务器时,需要一次性将整个文件上传完成。但是,如果文件比较大,上传速度较慢,或者网络不稳定,这种方式可能会导致上传失败或耗时过长。而Element文件切片上传则是将文件分割成多个小块进行上传,以提高上传效率和稳定性。 Element文件切片上传的原理是将文件按照一定的大小进行分割,例如将文件切分成大小为1MB的小块。然后,逐个上传每个小块,直到整个文件上传完成。在上传过程中,服务器会将接收到的每个小块按照顺序进行组合,最终合并为完整的文件。 Element文件切片上传的好处是可以有效解决上传大文件时的网络不稳定和耗时过长的问题。由于文件被切片上传,即使某个小块上传失败,也只需要重新上传该小块,而不需要重新上传整个文件。这样一方面可以节省上传时间,另一方面也减少了上传失败的可能性。 Element文件切片上传在实际应用中被广泛使用,特别是对于大型文件的上传或者网络环境较差的情况下,能够提升用户体验。在实现上,开发人员需要注意文件分割的大小、上传块序号的管理以及上传完成后的合并处理等方面的问题。 总而言之,Element文件切片上传是一种有效的文件上传方式,通过将文件分割成小块进行上传,可以提高上传效率和稳定性,并且适用于各种文件上传场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值