项目中有大容量得文件需要下载,服务器连接得设备比较多,同时下载得话,服务器肯定是受不了了,当时有两种想法
1: 限速下载
2:排队下载
虽然最后采用得是第二种方式,我也把第一种也实现了,记录下,分享给需要得朋友.
源码地址:实现了端点续传,和限速,这只是个demo,可以进行二次封装
切记,切记,切记
后边维护了一次,下载源码之后,覆盖下面一段代码到
FileDownloadHandler这个类里面,目前可以实现误差10 kb/s 还是比较好用得。
链接:https://download.csdn.net/download/fkgjdkblxckvbxbgb/11233046
当时去github上,有一位仁兄写的挺好得,但是由于项目里面一直用得是XUtil,用了几年,还比较稳定,不想换代码,死来想去,就去看了他得逻辑,修改了一下XUtil下载那一块得代码.
代码封装得还是挺完整,传入下载地址,保存位置,和一个回调监听,回调里面有下载状态回显
runnable.setIsDelFile(false); //不要删除上次未下载完毕,断点续传
runnable.setLimitDownSpeed(limitSpeed); //设置下载速度
这里如果设置了限制速度,那么是有限制得,如果不传入速度,那么就是不限速下载:主要代码不多,下载还是有一点点误差,因为Thread 睡眠得时间必须是整数,这个没办法了 。
原理比较简单,就是在文件流里面加了一个线程等待延时,具体得时间是根据设置得速度来计算,具体需要看详细源码得,直接下载代码看吧.
while ((len = bis.read(bytes)) != -1) {
long currentTime = System.currentTimeMillis();
bos.write(bytes, 0, len);
current += len;
if (callBackHandler != null) {
if (!callBackHandler.updateProgress(total, current, false)) {
return targetFile;
}
}
//=======================================================================
//2000 Kb限速。其他的不限速
if (LimitSpeed > 0 && LimitSpeed < 2001) {
long distanceSize = current - lastSave;
if (distanceSize > LimitSpeed * 512) {
long distanceTime = lastSaveTime + 1000 - currentTime;
try {
if (distanceTime > 100) {
Thread.sleep(distanceTime);
}
} catch (Exception e) {
e.printStackTrace();
}
lastSaveTime = currentTime;
lastSave = current;
}
}
//=======================================================================
}
package com.zxj.udp_playsync;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.demo.DownFileEntity;
import com.demo.DownRunnable;
import com.demo.DownStateListener;
public class MainActivity extends Activity implements View.OnClickListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
EditText et_speed_limit;
TextView tv_statues;
Button btn_down;
Button btn_cacel;
ProgressBar progressBar;
private void initView() {
tv_statues = (TextView) findViewById(R.id.tv_statues);
et_speed_limit = (EditText) findViewById(R.id.et_speed_limit);
btn_down = (Button) findViewById(R.id.btn_down);
btn_cacel = (Button) findViewById(R.id.btn_cacel);
btn_down.setOnClickListener(this);
btn_cacel.setOnClickListener(this);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_down:
startDown();
break;
case R.id.btn_cacel:
cacelDown();
et_speed_limit.setText("-1");
break;
}
}
DownRunnable runnable;
private void startDown() {
String downUrl = "http://dlied5.myapp.com/myapp/1104466820/sgame/2017_com.tencent.tmgp.sgame_h8931_1.44.1.19_716664.apk";
String savePath = "/sdcard/wzry.apk";
runnable = new DownRunnable(downUrl, savePath, new DownStateListener() {
@Override
public void downStateInfo(DownFileEntity entity) {
int speed = entity.getDownSpeed();
int progress = entity.getProgress();
int statues = entity.getDownState();
progressBar.setProgress(progress);
String showDesc = "速度: " + speed + " / 进度=" + progress + " /时间" + System.currentTimeMillis();
switch (statues) {
case DownFileEntity.DOWN_STATE_START:
showDesc = "开始下载 ==>" + showDesc;
break;
case DownFileEntity.DOWN_STATE_PROGRESS:
showDesc = "下载中 ==>" + showDesc;
break;
case DownFileEntity.DOWN_STATE_SUCCESS:
showDesc = "下载完成 ==>" + showDesc;
break;
case DownFileEntity.DOWN_STATE_FAIED:
showDesc = "下载中断 ==>" + showDesc;
break;
}
tv_statues.setText(showDesc);
}
});
int limitSpeed = Integer.parseInt(et_speed_limit.getText().toString().trim());
runnable.setIsDelFile(false); //不要删除上次未下载完毕,断点续传
runnable.setLimitDownSpeed(limitSpeed); //设置下载速度
Thread thread = new Thread(runnable);
thread.start();
}
public void cacelDown() {
if (runnable != null) {
runnable.stopDown();
}
}
}