Android系统Download模块

一、Download模块简介##

首先,Android Download模块主要由两个部分构成:DownloadManager以及DownloadProvider。 
  • DownloadManager:在Android L/M源码位置:frameworks/base/core/java/android/app/DownloadManager.java作用:提供接口供三方apk调用
  • DownloadManager在Android L/M源码位置:packages/providers/DownloadProvider/作用:具体下载的实现,包括相关文件下载信息的保存以及文件的下载。

二、DownloadManager介绍##

1、静态内部类####

DownloadManager是系统开放给第三方应用使用的类,包含两个静态内部类 -DownloadManager.Query和DownloadManager.Request。

  • DownloadManager.Request用来请求一个下载
  • DownloadManager.Query 用来查询下载信息

2、主要方法####

DownloadManager主要提供了一下主要方法:

  • enqueue(Request request):执行下载,返回downloadId,downloadId可用于查询下载信息。
  • remove(long ids):删除下载,若下载中取消下载。会同时删除下载文件和记录。
  • query(Query query)查询下载信息
  • getMaxBytesOverMobile(Context context)通过移动网络下载的最大字节数
  • getMimeTypeForDownloadedFile(long id)得到下载的mineType

三、DownloadProvider分析##

1、DownloadManager主要类介绍####

  • DownloadProvider:将下载信息insert到DB,启动下载服务类DownloadService
  • DownloadService:下载服务类,调用下载信息类DownlaodInfo,如果信息存在,则更新;否则,则新建该对象
  • DownloadInfo:下载信息类,启动下载线程类DownloadThread
  • DownloadThread:下载线程类,真正负责下载的线程,每次启动一个任务都会创建一个新的下载线程对象。进行下载前的过程检查、网络监测、路径检查等,保存文件……

2、下载流程分析####

下载流程时序图

Android系统Download模块_第1张图片

四、案例分析##

1、问题描述###

插入SD卡,将默认存储设置为SD卡,重启后进入Play Store,Facebook无法更新,下载pokemon go等应用,下载失败。

2、问题分析###

根据相应的Log分析,下载路径无效。根据系统Environment.java文件,应该动态实现下载路径的切换。
X项目默认存储方案是可动态获取路径的:

  • 当默认存储为内部存储时,有效路径应该为/storage/emulated/0/Android/data/……
  • 当默认存储为SD卡时,有效路径应该为/storage/sdcard1/Android/data/……

3、解决方案###

Play store下载流程图分析####

Android系统Download模块_第2张图片

解决思路

修改DownloadProvider类中insert(),确保下载记录的hint,data字段值正确从上面的流程图分析,思路就很明确了。当默认存储为SD卡时,在DownloadProvider.java中执行insert数据库之前,进行更新文件路径。将play store传给downloadProivder的无效路径(storage/emulated/0 )修改为storage/sdcard1,确保存储到数据库中的地址是有效的文件路径。

Some Tips###

  • Chrome,Play Store这些三方apk调用的都是系统自带的DownLoad模块下载数据。
  • Play Store下载apk后,自动删除apk
  • Downlaod记录保存在
    /data/data/com.android.providers.downloads/databases/downloads.db,有兴趣的童鞋可以push出来看一看

作者:流光易抛https://www.jianshu.com/p/bc0d6ad2669f

你可能感兴趣的:(android源码分析)