package activitytest.example.com.downandroid;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
EditText et_path;
EditText et_threadCount;
LinearLayout ll_pb;
String path;
int threadCount;
List<ProgressBar> pblist;
private static int runningThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//找到控件
et_path = findViewById(R.id.et_path);
et_threadCount = findViewById(R.id.et_threadCount);
ll_pb = findViewById(R.id.ll_pb);
//添加一个集合,用来存进度条的引用
pblist = new ArrayList<ProgressBar>();
}
//实现点击下载逻辑
public void click(View v){
//【1----------】获取下载路径
path = et_path.getText().toString().trim();
//【2----------】获取线程数量
String threadCountt = et_threadCount.getText().toString().trim();
threadCount = Integer.parseInt(threadCountt);
//【3----------】先把之前的进度条移除再添加进度条
ll_pb.removeAllViews();
//【4----------】动态的根据线程数量添加进度条
pblist.clear();
for(int i = 0 ; i< threadCount ; i++){
//把定义的item布局转换成一个View对象
ProgressBar pbView = (ProgressBar) View.inflate(getApplicationContext(),R.layout.item,null);
//把pbView添加到集合中
pblist.add(pbView);
//添加进度条
ll_pb.addView(pbView);
}
//【5----------】开始移植 因为联网,所以要创建一个子线程
new Thread(){
@Override
public void run() {
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
int code = conn.getResponseCode();
if (code == 200) {
int length = conn.getContentLength();
runningThread = threadCount;
System.out.println("length:" + length);
RandomAccessFile rafAccessFile = new RandomAccessFile(
getFilename(path), "rw");
rafAccessFile.setLength(length);
int blockSize = length / threadCount;
for (int i = 0; i < threadCount; i++) {
int starIndex = i * blockSize; // 每个线程下载的开始位置
int endIndex = (i + 1) * blockSize - 1;// 每个线程下载的结束位置
// 特殊情况 就是最后一个线程
if (i == threadCount - 1) {
endIndex = length - 1;
}
new DownLoadThread(starIndex, endIndex, i).start();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
public String getFilename(String path) { // 获取文件的名字
int start = path.lastIndexOf("/") + 1;
String substring = path.substring(start);
String fileName =MainActivity.this.getCacheDir().getPath()+"/"+substring;
return fileName;
}
private class DownLoadThread extends Thread {
private int starIndex;
private int endIndex;
private int threadId;
private int PbMaxSize; //代表当前线程下载的最大值
private int pblastPostion;//如果中断过,获取上次下载的位置
public DownLoadThread(int starIndex, int endIndex, int threadId) {
this.starIndex = starIndex;
this.endIndex = endIndex;
this.threadId = threadId;
}
@Override
public void run() {
try {
//【6----------】计算当前进度条的最大值
PbMaxSize = endIndex - starIndex;
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
File file = new File(getFilename(path) + threadId + ".txt");
if (file.exists() && file.length() > 0) {
FileInputStream fis = new FileInputStream(file);
BufferedReader bufr = new BufferedReader(new InputStreamReader(fis));
String lastPositionn = bufr.readLine(); // 读取出来的内容就是上次下载的位置
int lastPosition = Integer.parseInt(lastPositionn);
//给定义的进度条位置赋值
pblastPostion = lastPosition - starIndex;
starIndex = lastPosition +1;
fis.close();
}
conn.setRequestProperty("Range", "bytes=" + starIndex + "-"
+ endIndex);
int code = conn.getResponseCode();
if (code == 206) { // 200表示获取服务器资源全部成功,206表示请求部分资源成功
RandomAccessFile raf = new RandomAccessFile(
getFilename(path), "rw");
raf.seek(starIndex);
InputStream in = conn.getInputStream(); // 存的是ttt.exe
int len = -1;
byte[] buffer = new byte[1024 * 1024];
int total = 0; // 代表当前线程下载的大小
while ((len = in.read(buffer)) != -1) {
raf.write(buffer, 0, len);
total += len;
int currentThreadPosition = starIndex + total;
RandomAccessFile raff = new RandomAccessFile(getFilename(path) + threadId + ".txt", "rwd");
raff.write(String.valueOf(currentThreadPosition).getBytes());
raff.close();
//设置一下当前进度条的最大值和当前进度
pblist.get(threadId).setMax(PbMaxSize); //设置进度条的最大值
pblist.get(threadId).setProgress(pblastPostion+total);//设置进度条的当前位置
}
raf.close();// 释放资源
System.out.println("线程:" + threadId + "--下载完了");
synchronized (DownLoadThread.class) {
runningThread--;
if (runningThread == 0) { // 说明所有线程都执行完毕了
for (int i = 0; i < threadCount; i++) {
File deleFile = new File(getFilename(path) + i+ ".txt");
deleFile.delete();
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
集训day_08_3(多线程下载Android实现)
猜你喜欢
转载自blog.csdn.net/depths_p/article/details/81226989
今日推荐
周排行