事先聲明這個程式用到的主要的類檔案是《瘋狂android講義》上的知識。
我只是通過下載一個lrc歌詞檔案實驗了一下。
布局檔案如下
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:text="下載" /> <ProgressBar android:id="@+id/progressBar1" style="?android:attr/progressBarStyleHorizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_below="@+id/button1" /></RelativeLayout>
主要activity檔案
package com.example.downloadthread;import java.io.File;import java.io.IOException;import java.util.Timer;import java.util.TimerTask;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ProgressBar;public class MainActivity2 extends Activity {private ProgressBar progressBar;private Button button;private String filePath = "/mnt/sdcard/aaa.lrc";private String url = "http://box.zhangmen.baidu.com/bdlrc/9064/906474.lrc";private int threadNum = 4;private DownUtil downUtil;private int mDownStatus;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);button = (Button) findViewById(R.id.button1);progressBar = (ProgressBar) findViewById(R.id.progressBar1);button.setOnClickListener(new OnClickListener() {public void onClick(View v) {File file = new File(url);if (file.exists() == false) {try {file.createNewFile();} catch (IOException e) {e.printStackTrace();}}download();}});}final Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {if (msg.what == 0x123) {progressBar.setProgress(mDownStatus);}}};private void download() {downUtil = new DownUtil(threadNum, url, filePath);try {downUtil.download();} catch (Exception e) {e.printStackTrace();}final Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {// 擷取下載任務的完成比率double completeRate = downUtil.getCompleteRate();mDownStatus = (int) (completeRate * 100);// 發送訊息通知介面更新進度條handler.sendEmptyMessage(0x123);// 下載完全後取消任務調度if (mDownStatus >= 100) {timer.cancel();}}}, 0, 100);}}
下載協助類檔案
package com.example.downloadthread;import java.io.InputStream;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.URL;public class DownUtil {private int threadNum;private String strUrl;private String filePath;private DownloadThread threads[];// 定義下載的檔案的總大小private int fileSize;/** * @param threadNum * 線程個數 * @param url * 下載url * @param filePath * 檔案儲存體的路徑 * */public DownUtil(int threadNum, String url, String filePath) {super();this.threadNum = threadNum;this.strUrl = url;this.filePath = filePath;this.threads = new DownloadThread[threadNum];}void download() throws Exception {URL url = new URL(strUrl);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setConnectTimeout(5 * 1000);conn.setRequestMethod("GET");conn.setRequestProperty("Accept","image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");conn.setRequestProperty("Accept-Language", "zh-CN");conn.setRequestProperty("Charset", "UTF-8");conn.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");conn.setRequestProperty("Connection", "Keep-Alive");// 得到檔案大小fileSize = conn.getContentLength();conn.disconnect();int currentPartSize = fileSize / threadNum + 1;RandomAccessFile file = new RandomAccessFile(filePath, "rw");// 設定本地檔案的大小file.setLength(fileSize);file.close();for (int i = 0; i < threadNum; i++) {// 計算每條線程的下載的開始位置int startPos = i * currentPartSize;// 每個線程使用一個RandomAccessFile進行下載RandomAccessFile currentPart = new RandomAccessFile(filePath, "rw");// 定位該線程的下載位置currentPart.seek(startPos);// 建立下載線程threads[i] = new DownloadThread(startPos, currentPartSize,currentPart);// 啟動下載線程threads[i].start();}}class DownloadThread extends Thread {// 當前線程的下載位置private int startPos;// 定義當前線程負責下載的檔案大小private int currentPartSize;// 當前線程需要下載的檔案塊private RandomAccessFile currentPart;// 定義已經該線程已下載的位元組數public int length;public DownloadThread(int startPos, int currentPartSize,RandomAccessFile currentPart) {this.startPos = startPos;this.currentPartSize = currentPartSize;this.currentPart = currentPart;}@Overridepublic void run() {try {URL url = new URL(strUrl);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setConnectTimeout(5 * 1000);conn.setRequestMethod("GET");conn.setRequestProperty("Accept","image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, "+ "application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, "+ "application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, "+ "application/msword, */*");conn.setRequestProperty("Accept-Language", "zh-CN");conn.setRequestProperty("Charset", "UTF-8");InputStream inStream = conn.getInputStream();// 跳過startPos個位元組,表明該線程只下載自己負責哪部分檔案。inStream.skip(this.startPos);byte[] buffer = new byte[1024];int hasRead = 0;// 讀取網路資料,並寫入本地檔案while (length < currentPartSize&& (hasRead = inStream.read(buffer)) != -1) {currentPart.write(buffer, 0, hasRead);// 累計該線程下載的總大小length += hasRead;}currentPart.close();inStream.close();} catch (Exception e) {e.printStackTrace();}}}// 擷取下載的完成百分比public double getCompleteRate() {// 統計多條線程已經下載的總大小int sumSize = 0;for (int i = 0; i < threadNum; i++) {sumSize += threads[i].length;}// 返回已經完成的百分比return sumSize * 1.0 / fileSize;}public int getThreadNum() {return threadNum;}public void setThreadNum(int threadNum) {this.threadNum = threadNum;}public String getUrl() {return strUrl;}public void setUrl(String url) {this.strUrl = url;}public String getFilePath() {return filePath;}public void setFilePath(String filePath) {this.filePath = filePath;}}
由於需要sdcard卡的支援,所以還要許可權,我就都貼上了。
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />