绿茶浏览器的下载管理

1、下载相关的类


Android自带的下载管理原理其实很简单,整体基于内容提供者ContentProvider、内容解析者ContentResolver和内容监听者ContentObserver来实现下载的管理,通过ContentResolver操作ContentProvider来触发ContentObserver,从而执行真正的下载操作,下载过程又用到了消息机制。

DownloadListener

网页执行下载的回调接口。

DownloadManager

该类是下载管理的核心类,从名字就可以知道该类主要提供一些管理Download的API,以service的形式提供给开发人员的,即通过getSystemService。它的所有操作都是基于ContentResolver,其中触发真正下载的函数是enqueue(Request request)方法。
DownloadManager.Request下载请求

Downloads

声明了很多常量,主要提供给DownloadManager.(详见源码)
public staticfinal int STATUS_PAUSED = 191;
还没开始下载的暂停状态
public static final int STATUS_RUNNING = 192;
已经开始下载
public static final int STATUS_PAUSED_BY_APP= 193;
手动暂停下载
public static final int STATUS_SUCCEED = 200;
已经下载完全成功,但是也有一些状态值能代表成功了,用isSucccess函数来获得其他的信息

DownloadService

用于监听DownloadContent中的数据变化,从而执行相应的操作,例如:开启下载线程、暂停、重新开始下载等

DownloadThread

主要用于执行下载的操作,包括一些下载中异常的处理。

2、下载中的MimeType和ContentDisposition


常见MimeType:

MimeType extension
image/jpeg jpg
image/gif gif
text/html html
audio/mpeg mp3
audio/x-wav wav
video/x-msvideo avi

mime-type指定了下载资源的类型,如果为下载的文件指定mime-type有错误,可能出现不能被其他应用识别的情况,例如下载的图片时,如果指定mime-type类型为image/*,会导致文件管理器中的图片分类可能无法识别图片类型的文件,彩信无法发送图片等情况,这些应用都是通过mime-type识别图片的。

ContentDisposition

ContentDisposition主要在下载时用于猜文件名字

3、当点击了浏览器页面中的某个连接,为什么会下载?


点击浏览器中的链接,向服务器发送请求得到相应的资源,如果资源无法被浏览器的rendering engine处理,就会调用OnDownloadStart,这部分逻辑主要由内核处理。
在Android4.4以后部分下载链接没有回调OnDownloadStart,原因是Android4.3内核升级之后,在点击网页中的链接时,网页发送了GET的request,渲染引擎根据request信息里的MIME Type,判断是否支持在线播放该类型的视频,如果能够处理服务器返回的响应,支持了在线播放此类型的视频, 就不会回调onDownloadStart,也就是该链接不会产生下载事件,因此不会调用浏览器应用的回调onDownloadStart,而是直接通过网页打开播放。这样就导致部分音视频不能选择下载而只能直接播放,为满足项目项目中运营商规范,提供workround解决方案包括:长按处理、过滤url。

4、网络变化时的下载


在项目中经常遇到的下载问题是接打电话、收发短信和彩信、切换网络类型时遇到下载暂停后无法按要求自动恢复,此类问题的本质原因是网络状态发生了变化,因此解决这些问题主要是围绕网络变化的规律来展开。

理解网络类型

平时对网络类型的理解还不够准确,容易将wifi、3G、2G的类别混淆,网络类型主要包括Wifi、移动数据连接(4G、3G、2G),它们在底层的实现各不相同,像打电话、收发短信之类的功能都是与数据连接有关,使用这些功能的时候会对数据连接造成影响,但不会影响wifi。

由于两种网络类型有本质的区别,切换这两种类型的网络时会出现网络短暂的断开,导致下载暂停,下载的状态变为STATUS_WAITING_FOR_NETWORK,Android官方的自动恢复下载需要5分钟,为了符合项目规范的30秒内恢复下载,浏览器需要提前执行恢复下载。

恢复下载的时机

要想使恢复下载成功需具备以下条件:
1).网络的连接良好
2).支持断点续传(基本都支持)
依据这两个条件我们需要监听网络改变后的网络状态

Wifi状态的监听

需要注册广播:WifiManager.NETWORK_STATE_CHANGED_ACTION
只适用于监听Wifi关闭或打开过程的状态。Wifi打开需要一个过程,其DetailedState如下:
OBTAINING_IPADDR(分配IP地址)——>VERIFYING_POOR_LINK(不可靠的连接)——>CAPTIVE_PORTAL_CHECK(检查是否为强制用户)——>CONNECTED(连接完成,会发送ConnectivityManager.CONNECTIVITY_ACTION广播)
当wifi处于CONNECTED后可以执行恢复下载。
Wifi关闭过程的DetailedState一直是DISCONNECTED,可用于控制是否自动恢复。

数据连接状态的监听:

通过TelephonyManager的listen方法注册一个重载了onDataConnectionStateChanged方法的PhoneStateListener对象就可以实现监听

PhoneStateListener.onDataConnectionStateChanged()
只适用于监听数据连接改变时的状态,如2G和3G之间的切换,切换过程一般是经历连接-断开-连接过程,由于有时候2G和3G之间切换会平滑过渡,不会出现断开的情况,也就不会发送ConnectivityManager.CONNECTIVITY_ACTION的广播。

网络连接状态的监听:

需要注册广播:ConnectivityManager.CONNECTIVITY_ACTION
只适用于监听网络连接改变后处于connected时的状态,当数据连接的不同类型之间平滑切换就不能能通过此方式监听到。

PS:

此外网络中断下载也有可能与网络质量有关系,网络中断大部分会产生sockettimeoutexception,造成这种异常的情况有很多,需结合实际场景分析。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,347评论 19 139
  • iOS开发系列--网络开发 概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博、微信等,这些应用本身可...
    lichengjin阅读 9,117评论 2 7
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,233评论 25 709
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 13,851评论 6 13
  • Chapter2 单词和句段 1.As he listened to them talking, Tristran...
    姜小饼阅读 3,060评论 0 0