作者: beizhiying7 | 来源:发表于2014-08-15 11:19 被阅读137次

    绿茶浏览器的下载管理

    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,造成这种异常的情况有很多,需结合实际场景分析。

    相关文章

      网友评论

          本文标题:

          本文链接:https://www.haomeiwen.com/subject/geretttx.html