android多线程断点下载-带进度条和百分比进度显示效果

android多线程断点下载,带进度条和百分比显示,断点下载的临时数据保存到SD卡的文本文档中,建议可以保存到本地数据库中,这样可以提高存取效率,从而提高系统性能。

效果:

打开软件:

下载中:

下载完毕:

附代码如下:

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 {

//下载所使用的线程数

protected static final int threadCount = 3;

//下载完毕的标记

public static final int downloadOver = 1;

//更新下载进度标记

public static final int UPDATE_PROGRESS = 0;

//下载资源的路径输入框

private EditText et_path;

//下载的进度条

private ProgressBar pb;

//进度显示

private TextView tv_pb;

//当前累计下载的数据

int curDownCount=0;

//当前活动的下载线程数

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("当前进度:"+(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 {

//构造URL地址

URL url=new URL(path);

//打开连接

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

//设置请求超时的时间

conn.setConnectTimeout(5000);

//设置请求方式

conn.setRequestMethod("GET");

//获取相应码

int code=conn.getResponseCode();

if (code==200) {//请求成功

//获取请求数据的长度

int length=conn.getContentLength();

//设置进度条的最大值

pb.setMax(length);

//在客户端创建一个跟服务器文件大小相同的临时文件

RandomAccessFile raf=new RandomAccessFile("sdcard/setup.exe", "rwd");

//指定临时文件的长度

raf.setLength(length);

raf.close();

//假设3个线程去下载资源

//平均每一个线程要下载的文件的大小

int blockSize=length/threadCount;

for (int threadId = 1; threadId <= threadCount; threadId++) {

//当前线程下载数据的开始位置

int startIndex=blockSize*(threadId-1);

//当前线程下载数据的结束位置

int endIndex=blockSize*threadId-1;

//确定最后一个线程要下载数据的最大位置

if (threadId==threadCount) {

endIndex=length;

}

//显示下载数据的区间

System.out.println("线程【"+threadId+"】开始下载:"+startIndex+"---->"+endIndex);

//开启下载的子线程

new DownloadThread(path, threadId, startIndex, endIndex).start();

//当前下载活动的线程数加1

activeThread++;

System.out.println("当前活动的线程数:"+activeThread);

}

}else{//请求失败

System.out.println("服务器异常,下载失败!");

}

} catch (Exception e) {

e.printStackTrace();

System.out.println("服务器异常,下载失败!");

}

};

}.start();

}

/**

* 下载文件的子线程 每一个文件都下载对应的数据

* @author YUANYUAN

*

*/

public class DownloadThread extends Thread{

private String path;

private int threadId;

private int startIndex;

private int endIndex;

/**

* 构造方法

* @param path 下载文件的路径

* @param threadId 下载文件的线程

* @param startIndex 下载文件开始的位置

* @param endIndex 下载文件结束的位置

*/

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() {

//构造URL地址

try {

File tempFile=new File("sdcard/"+threadId+".txt");

//检查记录是否存在,如果存在读取数据,设置真实下载开始的位置

if (tempFile.exists()) {

FileInputStream fis=new FileInputStream(tempFile);

byte[] temp=new byte[1024];

int length=fis.read(temp);

//读取到已经下载的位置

int downloadNewIndex=Integer.parseInt(new String(temp, 0, length));

//计算出已经下载的数据长度

int areadyDown=downloadNewIndex-startIndex;

//累加已经下载的数据量

curDownCount+=areadyDown;

//设置进度条已经下载的数据量

pb.setProgress(curDownCount);

//设置重新开始下载的开始位置

startIndex=downloadNewIndex;

fis.close();

//显示真实下载数据的区间

System.out.println("线程【"+threadId+"】真实开始下载数据区间:"+startIndex+"---->"+endIndex);

}

URL url = new URL(path);

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

conn.setConnectTimeout(5000);

conn.setRequestMethod("GET");

//设置请求属性,请求部分资源

conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);

int code=conn.getResponseCode();

if (code==206) {//下载部分资源,正常返回的状态码为206

InputStream is=conn.getInputStream();//已经设置了请求的位置,所以返回的是对应的部分资源

//构建随机访问文件

RandomAccessFile raf=new RandomAccessFile("sdcard/setup.exe", "rwd");

//设置 每一个线程随机写文件开始的位置

raf.seek(startIndex);

//开始写文件

int len=0;

byte[] buffer=new byte[1024];

//该线程已经下载数据的长度

int total=0;

while((len=is.read(buffer))!=-1){//读取输入流

//记录当前线程已下载数据的长度

RandomAccessFile file=new RandomAccessFile("sdcard/"+threadId+".txt","rwd");

raf.write(buffer,0,len);//写文件

total+=len;//更新该线程已下载数据的总长度

System.out.println("线程【"+threadId+"】已下载数据:"+(total+startIndex));

//将已下载数据的位置记录写入到文件

file.write((startIndex+total+"").getBytes());

//累加已经下载的数据量

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+"】下载出现异常!!");

}finally{

//活动的线程数减少

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多线程断点下载-带进度条和百分比进度显示效果就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

以上是 android多线程断点下载-带进度条和百分比进度显示效果 的全部内容, 来源链接: utcz.com/z/352189.html

回到顶部