android开发多线程下载,Android 使用HttpURLConnection 实现多线程下载

本文介绍了一个使用Java实现的多线程下载工具类`DownUtil`,该类支持指定线程数量并行下载大文件,通过`RandomAccessFile`进行文件分段写入。同时,展示了`MainActivity`如何调用该工具类,通过`Handler`更新下载进度,并使用`TimerTask`定时获取下载完成百分比。
摘要由CSDN通过智能技术生成

工具类代码:package com.example.xiaocool.multithreadclient;

import java.io.InputStream;

import java.io.RandomAccessFile;

import java.net.HttpURLConnection;

import java.net.URL;

public class DownUtil

{

// 定义下载资源的路径

private String path;

// 指定所下载的文件的保存位置

private String targetFile;

// 定义需要使用多少线程下载资源

private int threadNum;

// 定义下载的线程对象

private DownThread[] threads;

// 定义下载的文件的总大小

private int fileSize;

public DownUtil(String path, String targetFile, int threadNum)

{

this.path = path;

this.threadNum = threadNum;

// 初始化threads数组

threads = new DownThread[threadNum];

this.targetFile = targetFile;

}

public void download() throws Exception

{

URL url = new URL(path);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setConnectTimeout(5 * 1000);

conn.setRequestMethod("GET");

conn.setRequestProperty(

"Accept",

"p_w_picpath/gif, p_w_picpath/jpeg, p_w_picpath/pjpeg, p_w_picpath/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("Connection", "Keep-Alive");

// 得到文件大小

fileSize = conn.getContentLength();

conn.disconnect();

int currentPartSize = fileSize / threadNum + 1;

RandomAccessFile file = new RandomAccessFile(targetFile, "rw");

// 设置本地文件的大小

file.setLength(fileSize);

file.close();

for (int i = 0; i 

{

// 计算每条线程的下载的开始位置

int startPos = i * currentPartSize;

// 每个线程使用一个RandomAccessFile进行下载

RandomAccessFile currentPart = new RandomAccessFile(targetFile,

"rw");

// 定位该线程的下载位置

currentPart.seek(startPos);

// 创建下载线程

threads[i] = new DownThread(startPos, currentPartSize,

currentPart);

// 启动下载线程

threads[i].start();

}

}

// 获取下载的完成百分比

public double getCompleteRate()

{

// 统计多条线程已经下载的总大小

int sumSize = 0;

for (int i = 0; i 

{

sumSize += threads[i].length;

}

// 返回已经完成的百分比

return sumSize * 1.0 / fileSize;

}

private class DownThread extends Thread

{

// 当前线程的下载位置

private int startPos;

// 定义当前线程负责下载的文件大小

private int currentPartSize;

// 当前线程需要下载的文件块

private RandomAccessFile currentPart;

// 定义已经该线程已下载的字节数

public int length;

public DownThread(int startPos, int currentPartSize,

RandomAccessFile currentPart)

{

this.startPos = startPos;

this.currentPartSize = currentPartSize;

this.currentPart = currentPart;

}

@Override

public void run()

{

try

{

URL url = new URL(path);

HttpURLConnection conn = (HttpURLConnection)url

.openConnection();

conn.setConnectTimeout(5 * 1000);

conn.setRequestMethod("GET");

conn.setRequestProperty(

"Accept",

"p_w_picpath/gif, p_w_picpath/jpeg, p_w_picpath/pjpeg, p_w_picpath/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 

&& (hasRead = inStream.read(buffer)) > 0)

{

currentPart.write(buffer, 0, hasRead);

// 累计该线程下载的总大小

length += hasRead;

}

currentPart.close();

inStream.close();

}

catch (Exception e)

{

e.printStackTrace();

}

}

}

}

MainActivity:package com.example.xiaocool.multithreadclient;

import android.os.Handler;

import android.os.Message;

import android.support.v7.app.ActionBarActivity;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.ProgressBar;

import java.util.Timer;

import java.util.TimerTask;

public class MainActivity extends ActionBarActivity {

EditText url;

EditText target;

Button downBn;

ProgressBar bar;

DownUtil downUtil;

private int mDownStatus;

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

url = (EditText) findViewById(R.id.url);

target = (EditText) findViewById(R.id.target);

downBn = (Button) findViewById(R.id.down);

bar = (ProgressBar) findViewById(R.id.bar);

// 创建一个Handler对象

final Handler handler = new Handler()

{

@Override

public void handleMessage(Message msg)

{

if (msg.what == 0x123)

{

bar.setProgress(mDownStatus);

}

}

};

downBn.setOnClickListener(new View.OnClickListener()

{

@Override

public void onClick(View v)

{

// 初始化DownUtil对象 最后一个参数指定线程数

downUtil = new DownUtil(url.getText().toString(),

target.getText().toString(), 6);

new Thread()

{

@Override

public void run()

{

try

{

// 开始下载

downUtil.download();

}

catch (Exception e)

{

e.printStackTrace();

}

// 定义美妙调度获取一次系统的完成进度

final Timer timer = new Timer();

timer.schedule(new TimerTask()

{

@Override

public void run()

{

// 获取下载任务的完成比例

double completeRate = downUtil.getCompleteRate();

mDownStatus = (int) (completeRate * 100);

handler.sendEmptyMessage(0x123);

// 下载完成后取消任务调度

if (mDownStatus >= 100)

{

timer.cancel();

}

}

}, 0, 100);

}

}.start();

}

});

}

}

93ef169bd61e9a19576db07b04bc1565.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值