在之前的文章中本猿曾介紹過Android N DownloadManager中已經采用了JobSchedule方式進行下載任務的調度,今天就開發(fā)過程中碰到的關于JobSchedule的一點小坑,總結出來供大家參考分析。
想了解更多關于Android N中DownloadManager的源碼分析請點擊下文:
問題背景
在項目中,項目采用基于源碼修改的DownloadManager進行下載任務,而出于控制下載流量的考慮,會額外對網絡訪問權限進行一定的處理。目前主要修改點有兩個:
- Helpers類中的scheduleJob方法,主要作用是通過schedule來喚起DownloadJobService,最終執(zhí)行下載操作。
- DownloadInfo類中的getRequiredNetworkType()方法,主要作用來返回下載任務需要的網絡類型。
問題描述
當前存在的問題是對于Android 7.0的手機共享出來的熱點,我們的下載任務一直處于等待下載狀態(tài),無法執(zhí)行。
問題結果
在前文已經介紹過DownloadManager啟動DownloadJobService是通過Helpers.scheduleJob()方法來調度任務,拉起DownloadJobService,最終完成下載功能的,
對于目前存在的問題,我們發(fā)現問題原因是由于scheduler.scheduleAsPackage()已經完成了調度工作,并返回了調度值為1。但為什么沒有調用DownloadJobService呢,我們最后還是注意到我們設置的網絡類型:
// We always require a network, but the type of network might be further
// restricted based on download request or user override
builder.setRequiredNetworkType(info.getRequiredNetworkType(info.mTotalBytes));
我們要注意到,此處setRequiredNetworkType設置了調度任務執(zhí)行需要的網絡類型,而當前DonwloadInfo連接手機熱點獲取的網絡類型為WIFI,由于需求要求控制訪問網絡請求的原因,所以我們對于所有網絡類型為WIFI的網絡,返回的類型為JobInfo.NETWORK_TYPE_UNMETERED,即只允許訪問非計費的網絡。
但是對于Android6.0與7.0版本的手機,開出的熱點識別出的NetworkInfo中mIsMetered對象為true, 而對于普通wifi中對于mIsMetered對象為false,這個標記值是用來標記當前網絡是否為計費網絡的標記位。對于手機網絡的熱點,此處他會識別為計費的網絡,而對于普通通過路由分出的熱點,會識別為非計費的網絡,因此針對這個問題,我們將需要的網絡類型設置為JobInfo.NETWORK_TYPE_ANY即可正常完成調用。
問題后記
我們從這里可以看出Android系統(tǒng)設計的細膩之處,對于訪問網絡更強大的支持可以更靈活的讓我們對手機網絡的訪問進行控制。
但有個最重要的事是:對于是否為手機熱點還不能單純的以這個字段來判斷,因為從Iphone上開出的熱點,當手機讀取的時候,這個mIsMetered對象又變成了true。
所以當有產品經理問你能不能識別當前連接的是wifi還是手機熱點時,千萬別急著說可以識別哦~O(∩_∩)O哈哈
大家對于Android 網絡請求有什么建議和見解歡迎留言指導~~~