編輯:關於Android編程
用過迅雷的同學都知道,迅雷有個功能叫做多線程,還有一個叫離線下載,我們這裡重點介紹一下多線程下載。多線程,顧名思義就是很多歌線程同時在運行,為什麼要提出多線程這個概念呢?因為有時候一個線程下載太慢了。舉個例子,比如小時候常做的數學題,一個人挖溝需要15天,那麼兩個人對著挖呢?
當然數學題上面兩個人的效率是不一樣的,我們這裡把這個問題簡化了一下,只是想大家明白,什麼是多線程,為什麼有多線程。在多線程上出現過一個問題,為什麼有要提出多線程?其實提出多線程是為了充分利用CPU的硬件資源,解決應用程序等待的問題。多線程是為了同步完成多項任務,不是為了提高運行效率,而是為了提高資源使用效率來提高系統的效率。線程是在同一時間需要完成多項任務的時候實現的。
2、思路
(1)獲取網絡連接
(2)初始化多線程下載信息,開始下載
(3)開辟硬盤空間,用於存放數據資源
(4)把從網絡獲取的數據放入申請的空間中
(5)下載完畢,關閉資源鏈接
給出一個下載400M電影的示意圖,如下所示:

RandomAccessFile支持隨機的訪問
HTTP的Range頭字段指定每個線程從文件的什麼位置開始下載。
<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+M6GitPrC673izvY8L3A+CjxwPjMuMSDJ6NbD0OjSqs/C1NjOxLz+tcTQxc+iPC9wPgo8cD48cHJlIGNsYXNzPQ=="brush:java;">RandomAccessFile randOut = new RandomAccessFile(this.saveFile, "rwd");
if(this.fileSize>0){
randOut.setLength(this.fileSize);//設置文件的大小
}
randOut.close(); //關閉該文件,使設置生效
3.2 設置下載鏈接,並且開始劃分下載部分
URL url = new URL(this.downloadUrl);
if(this.data.size() != this.threads.length){ //如果原先未曾下載或者原先的下載線程數與現在的線程數不一致
this.data.clear(); //將數據置空
for (int i = 0; i < this.threads.length; i++) { //遍歷線程池
this.data.put(i+1, 0);//初始化每條線程已經下載的數據長度為0
}
this.downloadedSize = 0; //設置已經下載的長度為0
}
3.3 開始下載文件
for (int i = 0; i < this.threads.length; i++) {
//通過特定的線程ID獲取該線程已經下載的數據長度
int downloadedLength = this.data.get(i+1);
//判斷線程是否已經完成下載,否則繼續下載
if(downloadedLength < this.block && this.downloadedSize < this.fileSize){
//初始化特定id的線程
this.threads[i] = new DownloadThread(this, url, this.saveFile, this.block, this.data.get(i+1), i+1);
//設置線程的優先級,Thread.NORM_PRIORITY = 5 Thread.MIN_PRIORITY = 1 Thread.MAX_PRIORITY = 10
this.threads[i].setPriority(7);
//啟動線程
this.threads[i].start();
}else{
this.threads[i] = null; //表明在線程已經完成下載任務
}
}
fileService.delete(this.downloadUrl); //如果存在下載記錄,刪除它們,然後重新添加 fileService.save(this.downloadUrl, this.data); //把已經下載的實時數據寫入數據庫
boolean notFinished = true;//下載未完成
// 循環判斷所有線程是否完成下載
while (notFinished) {
notFinished = false;//假定全部線程下載完成
for (int i = 0; i < this.threads.length; i++){
if (this.threads[i] != null && !this.threads[i].isFinished()) {//如果發現線程未完成下載
notFinished = true;//設置標志為下載沒有完成
//如果下載失敗,再重新在已經下載的數據長度的基礎上下載
if(this.threads[i].getDownloadedLength() == -1){
//重新開辟下載線程,代碼與上面一致
}
}
}
if(listener!=null){
listener.onDownloadSize(this.downloadedSize);
}//通知目前已經下載完成的數據長度
}
//下載完成刪除記錄
if(downloadedSize == this.fileSize){
fileService.delete(this.downloadUrl);
} 斷點續傳是說在下載的時候,我們因為某些原因,導致了下載的暫停,比如在電腦上,我們的電腦突然斷電了,手機上的網絡中斷了,都會導致當前的下載任務終止,那麼當我們再次回來的時候,程序應該是可以繼續下載的,不然前面下載的資源就都浪費了。
根據上面的描述,我們應該可以知道,實現斷點續傳,關鍵是實現下載的數據存儲在數據庫中,等到之後我們程序再次進入的時候,會到數據庫中去查詢一下數據,然後接著繼續下載。而存儲數據到數據庫並不是太復雜,難的是如何識別程序的哪些數據被下載了,哪些數據是沒有下載的,這裡,我們在下載的時候使用了下載的線程id做識別。
如果該線程id的數據沒有被完整下載,應該是不會存儲到數據庫的,那麼這一部分的數據就要重新下載,在下載完成之後,數據拼接起來就是一個完整的文件了。
Android動畫學習Demo(3) 沿著貝塞爾曲線移動的Property Animation
Property Animation中最重要,最基礎的一個類就是ValueAnimator了。Property Animation利用ValueAnimator來跟蹤記錄
Android基礎入門教程——7.5.5 WebView緩存問題
本節引言: 現在很多門戶類信息網站,比如虎嗅,ifanr,钛媒體等等的APP,簡單點說是信息閱讀類的APP,很多 都是直接嵌套一個WebView用
Android Zipalign工具優化Android APK應用
生成的Android應用APK文件最好進行優化,因為APK包的本質是一個zip壓縮文檔,經過優化
夏天手機太燙解決方法
已經到了燥熱的暑氣在體內積聚的季節,我們的智能手機也同樣對熱沒什麼抵抗力。在用手機的時候,電池和儲存器就會出現發熱的狀況。這種熱量積聚,不僅會導致手機運行變
我的Android進階之旅------)解決錯誤:You need to use a Theme.AppCompat theme (or descendant) with this activity.
#1、錯誤描述今天,想實現Activity不顯示標題欄的效果,在項目的A