http://www.ideasandroid.com/archives/328#more-328
本文將介紹在android平臺下如何實現多線程下載,大家都知道,android平臺使用java做為開發語言,所以java中支持的多線程下載方式在android平臺下都支持,其中主要有兩種方式可以實現多線程下載。
一種方式是使用很多個線程分別下載文件的不同部分,最后把所有下載完的文件合并成一個文件。另一種方式是使用java為我們提供的RandomAccessFile類實現多線程的下載。
從性能上分析,第二種方式的存取速度會慢一些,但開發起來較為容易,不需要進行合并文件等操作。本文將使用第二種方式來實現多線程下載,最終效果如下圖所示:
使用圖形界面來獲取需要下載的內容,并實時更新下載進度條,代碼如下所示:
android多線程斷點下載
http://llb988.blog.51cto.com/1940549/510035
Andorid多線程斷點續傳下載器
http://www.jcodecraeer.com/a/opensource/2015/0602/2978.html
Android 多線程下載 仿下載助手
http://blog.csdn.net/u011733020/article/details/47016715
本文將介紹在android平臺下如何實現多線程下載,大家都知道,android平臺使用java做為開發語言,所以java中支持的多線程下載方式在android平臺下都支持,其中主要有兩種方式可以實現多線程下載。
一種方式是使用很多個線程分別下載文件的不同部分,最后把所有下載完的文件合并成一個文件。另一種方式是使用java為我們提供的RandomAccessFile類實現多線程的下載。
從性能上分析,第二種方式的存取速度會慢一些,但開發起來較為容易,不需要進行合并文件等操作。本文將使用第二種方式來實現多線程下載,最終效果如下圖所示:

使用圖形界面來獲取需要下載的內容,并實時更新下載進度條,代碼如下所示:
import java.io.File; import java.net.URL; import java.net.URLConnection; import android.app.Activity; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; /** * Copyright (C) 2010 ideasandroid * 演示android多線程下載 * 歡迎訪問http://www.ideasandroid.com * 讓程序開發不再那么神秘 */ public class FileDownloadDemo extends Activity { private EditText downloadUrl; private EditText downloadFileName; private EditText downloadThreadNum; private Button downloadBt; private ProgressBar downloadProgressBar; private TextView progressMessage; private int downloadedSize = 0; private int fileSize = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); downloadUrl = (EditText) findViewById(R.id.downloadUrl); downloadFileName = (EditText) findViewById(R.id.downloadFileName); downloadThreadNum = (EditText) findViewById(R.id.downloadThreadNum); progressMessage = (TextView) findViewById(R.id.progressMessage); downloadBt = (Button) findViewById(R.id.downloadBt); downloadProgressBar = (ProgressBar) findViewById(R.id.downloadProgressBar); downloadProgressBar.setVisibility(View.VISIBLE); downloadProgressBar.setMax(100); downloadProgressBar.setProgress(0); downloadBt.setOnClickListener(new OnClickListener() { public void onClick(View v) { download(); } }); } private void download() { // 獲取SD卡目錄 String dowloadDir = Environment.getExternalStorageDirectory() + "/ideasdownload/"; File file = new File(dowloadDir); //創建下載目錄 if (!file.exists()) { file.mkdirs(); } //讀取下載線程數,如果為空,則單線程下載 int downloadTN = Integer.valueOf("".equals(downloadThreadNum.getText() .toString()) ? "1" : downloadThreadNum.getText().toString()); //如果下載文件名為空則獲取Url尾為文件名 int fileNameStart = downloadUrl.getText().toString().lastIndexOf("/"); String fileName = "".equals(downloadFileName.getText().toString()) ? downloadUrl .getText().toString().substring(fileNameStart) : downloadFileName.getText().toString(); //開始下載前把下載按鈕設置為不可用 downloadBt.setClickable(false); //進度條設為0 downloadProgressBar.setProgress(0); //啟動文件下載線程 new downloadTask(downloadUrl.getText().toString(), Integer .valueOf(downloadTN), dowloadDir + fileName).start(); } Handler handler = new Handler() { @Override public void handleMessage(Message msg) { //當收到更新視圖消息時,計算已完成下載百分比,同時更新進度條信息 int progress = (Double.valueOf((downloadedSize * 1.0 / fileSize * 100))).intValue(); if (progress == 100) { downloadBt.setClickable(true); progressMessage.setText("下載完成!"); } else { progressMessage.setText("當前進度:" + progress + "%"); } downloadProgressBar.setProgress(progress); } }; /** * @author ideasandroid * 主下載線程 */ public class downloadTask extends Thread { private int blockSize, downloadSizeMore; private int threadNum = 5; String urlStr, threadNo, fileName; public downloadTask(String urlStr, int threadNum, String fileName) { this.urlStr = urlStr; this.threadNum = threadNum; this.fileName = fileName; } @Override public void run() { FileDownloadThread[] fds = new FileDownloadThread[threadNum]; try { URL url = new URL(urlStr); URLConnection conn = url.openConnection(); //獲取下載文件的總大小 fileSize = conn.getContentLength(); //計算每個線程要下載的數據量 blockSize = fileSize / threadNum; // 解決整除后百分比計算誤差 downloadSizeMore = (fileSize % threadNum); File file = new File(fileName); for (int i = 0; i < threadNum; i++) { //啟動線程,分別下載自己需要下載的部分 FileDownloadThread fdt = new FileDownloadThread(url, file, i * blockSize, (i + 1) * blockSize - 1); fdt.setName("Thread" + i); fdt.start(); fds[i] = fdt; } boolean finished = false; while (!finished) { // 先把整除的余數搞定 downloadedSize = downloadSizeMore; finished = true; for (int i = 0; i < fds.length; i++) { downloadedSize += fds[i].getDownloadSize(); if (!fds[i].isFinished()) { finished = false; } } //通知handler去更新視圖組件 handler.sendEmptyMessage(0); //休息1秒后再讀取下載進度 sleep(1000); } } catch (Exception e) { } } } }
import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.net.URL; import java.net.URLConnection; import android.util.Log; /** * Copyright (C) 2010 ideasandroid * 演示android多線程下載 * 歡迎訪問http://www.ideasandroid.com * 讓程序開發不再那么神秘 * * 單個下載線程 */ public class FileDownloadThread extends Thread{ private static final int BUFFER_SIZE=1024; private URL url; private File file; private int startPosition; private int endPosition; private int curPosition; //用于標識當前線程是否下載完成 private boolean finished=false; private int downloadSize=0; public FileDownloadThread(URL url,File file,int startPosition,int endPosition){ this.url=url; this.file=file; this.startPosition=startPosition; this.curPosition=startPosition; this.endPosition=endPosition; } @Override public void run() { BufferedInputStream bis = null; RandomAccessFile fos = null; byte[] buf = new byte[BUFFER_SIZE]; URLConnection con = null; try { con = url.openConnection(); con.setAllowUserInteraction(true); //設置當前線程下載的起點,終點 con.setRequestProperty("Range", "bytes=" + startPosition + "-" + endPosition); //使用java中的RandomAccessFile 對文件進行隨機讀寫操作 fos = new RandomAccessFile(file, "rw"); //設置開始寫文件的位置 fos.seek(startPosition); bis = new BufferedInputStream(con.getInputStream()); //開始循環以流的形式讀寫文件 while (curPosition < endPosition) { int len = bis.read(buf, 0, BUFFER_SIZE); if (len == -1) { break; } fos.write(buf, 0, len); curPosition = curPosition + len; if (curPosition > endPosition) { downloadSize+=len - (curPosition - endPosition) + 1; } else { downloadSize+=len; } } //下載完成設為true this.finished = true; bis.close(); fos.close(); } catch (IOException e) { Log.d(getName() +" Error:", e.getMessage()); } } public boolean isFinished(){ return finished; } public int getDownloadSize() { return downloadSize; } }
android多線程斷點下載
http://llb988.blog.51cto.com/1940549/510035
Andorid多線程斷點續傳下載器
http://www.jcodecraeer.com/a/opensource/2015/0602/2978.html
Android 多線程下載 仿下載助手
http://blog.csdn.net/u011733020/article/details/47016715
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
