DownloadManager分析(2)
昨天說到:
- DownloadManager分發(fā)任務(wù)給DownloadProvider
- DownloadProvider調(diào)用DownloadService
- DownloadService真正執(zhí)行下載操作
所以DownloadProvider做了什么便锨,怎么啟動DownloadService的?然后DownloadSerivce又是怎么實現(xiàn)下載的?
DownloadProvider做了什么
DownloadProvider的描述是:
Allows application to interact with the download manager.
允許應(yīng)用和download manager之間進行交互嘉栓。
Application可以是不同的Application催束,DownloadProvider
繼承了ContentProvider
肠鲫,所以可以實現(xiàn)數(shù)據(jù)共享牡整,事實上我們會發(fā)現(xiàn)下載到的內(nèi)容都會被顯示在「下載」這個原生APP里面次坡,當(dāng)然顯示與否在DownloadManager里面是可以打開/關(guān)閉的。
前面分析到兼蕊,Android N之前初厚,DownloadManager
會把request以ContentValues
形式pass給DownloadProvider.insert()
,然后進行異步下載件蚕。
//傳遞URI和Content Values給ContentResolver
Uri downloadUri = mResolver.insert(Downloads.Impl.CONTENT_URI, values);
DownloadProvider的insert方法孙技,將下載信息寫入數(shù)據(jù)庫,包括下載鏈接地址等信息排作,然后會啟動DownloadService
這個Service:
//連請求頭都寫入了數(shù)據(jù)庫
insertRequestHeaders(db, rowID, values);
//啟動DownloadService
context.startService(new Intent(context, DownloadService.class));
notifyContentChanged(uri, match);
return ContentUris.withAppendedId(Downloads.CONTENT_URI, rowID);
DownloadService做了什么
UpdateThread
DownloadService
會利用updateFromProvider
從provider的數(shù)據(jù)庫里獲取下載的請求牵啦,然后啟動UpdateThread
線程,這個線程會不斷地查找數(shù)據(jù)庫里還有沒有下載任務(wù)妄痪,以及還有沒有未完成的任務(wù)哈雏,直到完成才退出。
//UpdateThread的run方法
for (;;) {
synchronized (DownloadService.this) {
if (mUpdateThread != this) {
throw new IllegalStateException(
"multiple UpdateThreads in DownloadService");
}
if (!mPendingUpdate) {
mUpdateThread = null;
if (!keepService) {
stopSelf();
}
if (wakeUp != Long.MAX_VALUE) {
scheduleAlarm(wakeUp);
}
return;
}
mPendingUpdate = false;
}
...
...
}
DownloadThread
DownloadThread
真正實現(xiàn)了下載衫生,里面有很多功能裳瘪,比如開始、暫停罪针、斷點續(xù)傳彭羹。每個下載任務(wù)都是獨立的線程,需要同步鎖/線程池來限制下載數(shù)量泪酱。
有這些方法:
- excuteDownload 執(zhí)行下載
- setupDestinationFile 設(shè)置目標位置派殷,如果位置已經(jīng)有了file还最,就繼續(xù)下載,實現(xiàn)了斷點續(xù)傳
- addRequestHeaders 添加請求頭
- checkConnectivity 檢查鏈接
- readFromResponse 讀取response
- writeDataToDestination 寫數(shù)據(jù)
- reportProgress 報告進度
- checkPauseOrCanceled 檢查暫驼毕В或取消
- cleanUpDestination 清空目標位置
- notifyDownloadComplete 通知下載完成(更新數(shù)據(jù)庫/發(fā)送廣播)
5~8是一個loop拓轻,不停地獲取網(wǎng)絡(luò)數(shù)據(jù)流,檢查下載是否暫停经伙。
關(guān)鍵的下載操作都是在DownloadThread
里面實現(xiàn)的扶叉,如果想?yún)⒖季蛠磉@里看吧。另外帕膜,Android N之后DownloadProvider
引入了Job Schedule
辜梳,會將任務(wù)加入計劃,滿足指定條件再執(zhí)行操作泳叠,App不用駐留作瞄,可以省電,大概是這樣子危纫。
總結(jié)一下:
graph LR
DownloadManager-->DownloadProvider
DownloadProvider-->DownloadService
DownloadService-->UpdateThread
DownloadService-->DownloadThread
UpdateThread-->DownloadProvider
-Dec30
Reference:
[1]http://www.reibang.com/p/c9dc04af2f54#
[2]http://blog.csdn.net/zhiyi2010/article/details/19152979
[3]http://blog.csdn.net/qq_31726827/article/details/50462025