Android中级篇之多线程下载
Android中级篇之多线程下载
要是先多线程下载,则必须对同一个文件可任意位置的写入 ,java中提供这样一个类可任意写入RandomAccessFile 。通过多线程,可将文件分割成多个子断,每一个线程只需下载一段文件即可。实现效果如图:
下面看代码部分:
1.布局文件 main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="下载路径"
- />
- <EditText
- android:id="@+id/mEditText"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:text="http://android.yesky.com/uploads/attachments/2010-04/27/a5964152.jpg"/>
- <ProgressBar
- android:id="@+id/mBar"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:visibility="invisible"
- style="?android:attr/progressBarStyleHorizontal"/>
- <Button
- android:id="@+id/mButton"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="下载"/>
- </LinearLayout>
2.下载工具类 Download.java
- package com.yin.downloader.utils;
- import java.io.File;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.RandomAccessFile;
- import java.net.HttpURLConnection;
- import java.net.MalformedURLException;
- import java.net.URL;
- import android.content.Context;
- import android.util.Log;
- public class Download {
- private String SDPath = null;
- private static final String TAG = "com.yin.download";
- private RandomAccessFile randomFile = null;
- private URL url;
- private Context context;
- private String urlStr;
- private String fileName;
- private int fileSize;
- private int totalReadSize;
- public Download(String urlStr,String fileName,String SDPath,Context context){
- this.context = context;
- this.fileName = fileName;
- this.urlStr = urlStr;
- this.SDPath = SDPath;
- }
- public void downloadFile(){
- try {
- File file = new File(SDPath+fileName);
- url = new URL(urlStr);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setRequestMethod("GET");
- //获得下载文件的大小
- fileSize = conn.getContentLength();
- //设置线程的大小,考虑手机的性能,并不是越大越好
- int threadSize = 3;
- //每个线程下载文件+的部分大小 +1 避免文件下载不完全
- int block = fileSize / threadSize +1;
- for(int i=0;i<3;i++){
- int startPosition = i * block;
- //创建可任意位置读取的文件
- randomFile = new RandomAccessFile(file, "rw");
- randomFile.seek(startPosition);
- new DownloadThread(i+1, startPosition, block, randomFile).start();
- }
- } catch (MalformedURLException e) {
- Log.e(TAG, "MalformedURLException");
- e.printStackTrace();
- } catch (IOException e) {
- Log.e(TAG, "IOException");
- e.printStackTrace();
- }
- }
- //下载文件的线程
- private class DownloadThread extends Thread{
- private int threadID;
- private int startPosition;
- private int block;
- private RandomAccessFile randomFile;
- public DownloadThread(int threadID, int startPosition, int block,
- RandomAccessFile randomFile) {
- super();
- this.threadID = threadID;
- this.startPosition = startPosition;
- this.block = block;
- this.randomFile = randomFile;
- }
- public void run() {
- try {
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setRequestMethod("GET");
- //文件下载位置 规定的格式 “byte=xxxx-”
- String start = "bytes="+startPosition + "-";
- //设置文件开始的下载位置
- conn.setRequestProperty("Range", start);
- InputStream is = conn.getInputStream();
- byte[] buffer = new byte[4*1024];
- int len = -1;
- int readFileSize = 0;
- while((readFileSize < block) && ((len = is.read(buffer)) != -1)){
- randomFile.write(buffer,0,len);
- readFileSize += len ;
- totalReadSize += readFileSize;
- }
- System.out.println("线程 :"+threadID+" 下载完成");
- is.close();
- randomFile.close();
- conn.disconnect();
- } catch (IOException e) {
- Log.e(TAG+":child", "IOException");
- e.printStackTrace();
- }
- }
- }
- public int getFileSize() {
- return fileSize;
- }
- public void setFileSize(int fileSize) {
- this.fileSize = fileSize;
- }
- public int getTotalReadSize() {
- return totalReadSize;
- }
- public void setTotalReadSize(int totalReadSize) {
- this.totalReadSize = totalReadSize;
- }
- }
|
评论暂时关闭