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

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

效果:

打开软件:

505b894cac170d8b8fb1c1c53c1b0fb7.png

下载中:

f929e4060d09d98f1136112d862f665e.png

下载完毕:

906490062d897a83ee919b5598518e3e.png

附代码如下:

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值