android多線程斷點下載-帶進度條和百分比進度顯示效果
android多線程斷點下載,帶進度條和百分比顯示,斷點下載的臨時數(shù)據(jù)保存到SD卡的文本文檔中,建議可以保存到本地數(shù)據(jù)庫中,這樣可以提高存取效率,從而提高系統(tǒng)性能。
效果:
打開軟件:
下載中:
下載完畢:
附代碼如下:
package com.yy.multiDownloadOfBreakPoint; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.TextUtils; import android.view.View; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; /** * 多線程斷點下載實例 * @author YUANYUAN * */ public class MainActivity extends Activity { //下載所使用的線程數(shù) protected static final int threadCount = 3; //下載完畢的標(biāo)記 public static final int downloadOver = 1; //更新下載進度標(biāo)記 public static final int UPDATE_PROGRESS = 0; //下載資源的路徑輸入框 private EditText et_path; //下載的進度條 private ProgressBar pb; //進度顯示 private TextView tv_pb; //當(dāng)前累計下載的數(shù)據(jù) int curDownCount=0; //當(dāng)前活動的下載線程數(shù) protected static int activeThread; //加入消息處理機制 private Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what) { case downloadOver: Toast.makeText(MainActivity.this, "文件已下載完畢!", Toast.LENGTH_LONG).show(); tv_pb.setText("下載完成"); break; case UPDATE_PROGRESS: //更新進度顯示 tv_pb.setText("當(dāng)前進度:"+(pb.getProgress()*100/pb.getMax())+"%"); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_path=(EditText) findViewById(R.id.et_path); et_path.setText("http://192.168.2.114:8080/sqlite.exe"); pb=(ProgressBar) findViewById(R.id.pb); tv_pb=(TextView) findViewById(R.id.tv_pb); } /** * 開始下載 * @param view */ public void down(View view){ //獲取下載資源的路徑 final String path=et_path.getText().toString().trim(); //判斷資源路徑是否為空 if (TextUtils.isEmpty(path)) { Toast.makeText(this, "請輸入下載資源的路徑", Toast.LENGTH_LONG).show(); return; } //開啟一個線程進行下載 new Thread(){ public void run() { try { //構(gòu)造URL地址 URL url=new URL(path); //打開連接 HttpURLConnection conn=(HttpURLConnection) url.openConnection(); //設(shè)置請求超時的時間 conn.setConnectTimeout(5000); //設(shè)置請求方式 conn.setRequestMethod("GET"); //獲取相應(yīng)碼 int code=conn.getResponseCode(); if (code==200) {//請求成功 //獲取請求數(shù)據(jù)的長度 int length=conn.getContentLength(); //設(shè)置進度條的最大值 pb.setMax(length); //在客戶端創(chuàng)建一個跟服務(wù)器文件大小相同的臨時文件 RandomAccessFile raf=new RandomAccessFile("sdcard/setup.exe", "rwd"); //指定臨時文件的長度 raf.setLength(length); raf.close(); //假設(shè)3個線程去下載資源 //平均每一個線程要下載的文件的大小 int blockSize=length/threadCount; for (int threadId = 1; threadId <= threadCount; threadId++) { //當(dāng)前線程下載數(shù)據(jù)的開始位置 int startIndex=blockSize*(threadId-1); //當(dāng)前線程下載數(shù)據(jù)的結(jié)束位置 int endIndex=blockSize*threadId-1; //確定最后一個線程要下載數(shù)據(jù)的最大位置 if (threadId==threadCount) { endIndex=length; } //顯示下載數(shù)據(jù)的區(qū)間 System.out.println("線程【"+threadId+"】開始下載:"+startIndex+"---->"+endIndex); //開啟下載的子線程 new DownloadThread(path, threadId, startIndex, endIndex).start(); //當(dāng)前下載活動的線程數(shù)加1 activeThread++; System.out.println("當(dāng)前活動的線程數(shù):"+activeThread); } }else{//請求失敗 System.out.println("服務(wù)器異常,下載失??!"); } } catch (Exception e) { e.printStackTrace(); System.out.println("服務(wù)器異常,下載失??!"); } }; }.start(); } /** * 下載文件的子線程 每一個文件都下載對應(yīng)的數(shù)據(jù) * @author YUANYUAN * */ public class DownloadThread extends Thread{ private String path; private int threadId; private int startIndex; private int endIndex; /** * 構(gòu)造方法 * @param path 下載文件的路徑 * @param threadId 下載文件的線程 * @param startIndex 下載文件開始的位置 * @param endIndex 下載文件結(jié)束的位置 */ public DownloadThread(String path, int threadId, int startIndex, int endIndex) { this.path = path; this.threadId = threadId; this.startIndex = startIndex; this.endIndex = endIndex; } @Override public void run() { //構(gòu)造URL地址 try { File tempFile=new File("sdcard/"+threadId+".txt"); //檢查記錄是否存在,如果存在讀取數(shù)據(jù),設(shè)置真實下載開始的位置 if (tempFile.exists()) { FileInputStream fis=new FileInputStream(tempFile); byte[] temp=new byte[1024]; int length=fis.read(temp); //讀取到已經(jīng)下載的位置 int downloadNewIndex=Integer.parseInt(new String(temp, 0, length)); //計算出已經(jīng)下載的數(shù)據(jù)長度 int areadyDown=downloadNewIndex-startIndex; //累加已經(jīng)下載的數(shù)據(jù)量 curDownCount+=areadyDown; //設(shè)置進度條已經(jīng)下載的數(shù)據(jù)量 pb.setProgress(curDownCount); //設(shè)置重新開始下載的開始位置 startIndex=downloadNewIndex; fis.close(); //顯示真實下載數(shù)據(jù)的區(qū)間 System.out.println("線程【"+threadId+"】真實開始下載數(shù)據(jù)區(qū)間:"+startIndex+"---->"+endIndex); } URL url = new URL(path); HttpURLConnection conn=(HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); //設(shè)置請求屬性,請求部分資源 conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex); int code=conn.getResponseCode(); if (code==206) {//下載部分資源,正常返回的狀態(tài)碼為206 InputStream is=conn.getInputStream();//已經(jīng)設(shè)置了請求的位置,所以返回的是對應(yīng)的部分資源 //構(gòu)建隨機訪問文件 RandomAccessFile raf=new RandomAccessFile("sdcard/setup.exe", "rwd"); //設(shè)置 每一個線程隨機寫文件開始的位置 raf.seek(startIndex); //開始寫文件 int len=0; byte[] buffer=new byte[1024]; //該線程已經(jīng)下載數(shù)據(jù)的長度 int total=0; while((len=is.read(buffer))!=-1){//讀取輸入流 //記錄當(dāng)前線程已下載數(shù)據(jù)的長度 RandomAccessFile file=new RandomAccessFile("sdcard/"+threadId+".txt","rwd"); raf.write(buffer,0,len);//寫文件 total+=len;//更新該線程已下載數(shù)據(jù)的總長度 System.out.println("線程【"+threadId+"】已下載數(shù)據(jù):"+(total+startIndex)); //將已下載數(shù)據(jù)的位置記錄寫入到文件 file.write((startIndex+total+"").getBytes()); //累加已經(jīng)下載的數(shù)據(jù)量 curDownCount+=len; //更新進度條【進度條的更新可以在非UI線程直接更新,具體見底層源代碼】 pb.setProgress(curDownCount); //更新下載進度 Message msg=Message.obtain(); msg.what=UPDATE_PROGRESS; handler.sendMessage(msg); file.close(); } is.close(); raf.close(); //提示下載完畢 System.out.println("線程【"+threadId+"】下載完畢"); } } catch (Exception e) { e.printStackTrace(); System.out.println("線程【"+threadId+"】下載出現(xiàn)異常?。?); }finally{ //活動的線程數(shù)減少 activeThread--; if (activeThread==0) { for (int i = 1; i <= threadCount; i++) { File tempFile=new File("sdcard/"+i+".txt"); tempFile.delete(); } System.out.println("下載完畢,已清除全部臨時文件"); //界面消息提示下載完畢 Message msg=new Message(); msg.what=downloadOver; handler.sendMessage(msg); } } } } }
以上這篇android多線程斷點下載-帶進度條和百分比進度顯示效果就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
- Android 下載文件通知欄顯示進度條功能的實例代碼
- Android編程實現(xiàn)顯示在標(biāo)題上的進度條功能【附源碼下載】
- Android實現(xiàn)標(biāo)題上顯示隱藏進度條效果
- Android多線程+單線程+斷點續(xù)傳+進度條顯示下載功能
- Android自定義多節(jié)點進度條顯示的實現(xiàn)代碼(附源碼)
- Android使用AsyncTask下載圖片并顯示進度條功能
- Android 進度條顯示在標(biāo)題欄的實現(xiàn)方法
- Android上傳文件到服務(wù)端并顯示進度條
- Android實現(xiàn)支持進度條顯示的短信備份工具類
- android實現(xiàn)動態(tài)顯示隱藏進度條
相關(guān)文章
Android實現(xiàn)滑動刪除操作(PopupWindow)
這篇文章主要介紹了Android ListView結(jié)合PopupWindow實現(xiàn)滑動刪除的相關(guān)資料,需要的朋友可以參考下2016-07-07Android MenuItem 自定義長按事件的實現(xiàn)
這篇文章主要介紹了Android MenuItem 自定義長按事件的實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08Android實戰(zhàn)教程第六篇之一鍵鎖屏應(yīng)用問題解決
這篇文章主要為大家詳細介紹了Android一鍵鎖屏應(yīng)用開發(fā)過程中出現(xiàn)問題的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11Flutter List數(shù)組避免插入重復(fù)數(shù)據(jù)的實現(xiàn)
這篇文章主要介紹了Flutter List數(shù)組避免插入重復(fù)數(shù)據(jù)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Android自定義view系列之99.99%實現(xiàn)QQ側(cè)滑刪除效果實例代碼詳解
這篇文章給大家介紹android自定義view系列之99.99%實現(xiàn)QQ側(cè)滑刪除效果,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友參考下吧2016-09-09Flutter Http分塊下載與斷點續(xù)傳的實現(xiàn)
這篇文章主要介紹了Flutter Http分塊下載與斷點續(xù)傳的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03Android LeakCanary檢測內(nèi)存泄露原理
這篇文章主要介紹了分析LeakCanary檢測內(nèi)存泄露原理,幫助大家更好的理解和學(xué)習(xí)使用Android開發(fā),感興趣的朋友可以了解下2021-03-03Android編譯出現(xiàn)Warning:Mapping?new?ns?to?old?ns報錯的解決方案
android在編譯的過程中難免會出現(xiàn)些錯誤,下面這篇文章主要給大家介紹了關(guān)于Android編譯出現(xiàn)Warning:Mapping?new?ns?to?old?ns報錯的解決方案,需要的朋友可以參考下2023-02-02Android 判斷當(dāng)前語言環(huán)境是否是中文環(huán)境
本文主要介紹了Android 判斷當(dāng)前語言環(huán)境是否是中文環(huán)境的方法。具有很好的參考價值。下面跟著小編一起來看下吧2017-04-04