@Tyhj
2017-02-24T16:50:34.000000Z
字数 4872
阅读 1517
Android
就是将服务器上的文件分为几段,然后去分段下载,然后用RandomAccessFile这个类将文件组合到一起。
就是把已经下载的文件进度保存起来,再次下载的时候就继续下载。
package demand.example.tyhj.download;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MainActivity extends AppCompatActivity {
EditText editText;
Button button;
ProgressBar progressBar;
//文件长度
private int leanth;
//下载进度
private int total = 0;
//下载地址
private URL url;
//下载的文件
private File file;
//开始或者暂停下载
private boolean downLoading;
//用于保存下载线程(每段为一个线程)
private List<HashMap<String, Integer>> threadList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
threadList = new ArrayList<>();
editText = (EditText) findViewById(R.id.fileUrl);
button = (Button) findViewById(R.id.btn_download);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
//editText.setText("http://192.168.31.215:8080/Download/downLoadFile/move.mp4");
progressBar.setProgress(0);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (downLoading) {
downLoading = false;
button.setText("开始");
return;
}
downLoading = true;
button.setText("暂停");
if (threadList.size() == 0) {
//之前没有开始下载文件
new Thread(new Runnable() {
@Override
public void run() {
try {
url = new URL(editText.getText().toString());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(500);
//获取文件的大小
leanth = connection.getContentLength();
Log.e("开始长度:",leanth+"");
//设置进度条的长度
progressBar.setMax(leanth/1024);
//文件不存在
if (leanth < 0) {
handler.obtainMessage(1, 0, 0).sendToTarget();
return;
}
//保存文件地址
file = new File(Environment.getExternalStorageDirectory(), getName(editText.getText().toString()));
//设置分割下载的文件
RandomAccessFile random = new RandomAccessFile(file, "rw");
random.setLength(leanth);
//分为三段下载
int blockSize = leanth / 3;
for (int i = 0; i < 3; i++) {
int begin = i * blockSize;
int end = (i + 1) * blockSize;
if (i == 2)
end = leanth;
//设置每段下载的长度
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("begin", begin);
map.put("end", end);
map.put("finished", 0);
threadList.add(map);
//创建线程下载文件
Thread t = new Thread(new Download(begin, end, file, url, i));
t.start();
}
} catch (MalformedURLException e) {
Toast.makeText(MainActivity.this, "Url错误", Toast.LENGTH_SHORT).show();
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} else {
//恢复下载
for (int i = 0; i < threadList.size(); i++) {
HashMap<String, Integer> map = threadList.get(i);
int begin = map.get("begin");
int end = map.get("end");
int finished = map.get("finished");
Thread t = new Thread(new Download(begin + finished, end, file, url, i));
t.start();
}
}
}
});
}
//获取现在文件的名字
private String getName(String url) {
return url.substring(url.lastIndexOf("/") + 1, url.length());
}
//下载类
class Download implements Runnable {
private int begin;
private int end;
private File file;
private URL url;
private int id;
public Download(int begin, int end, File file, URL url, int id) {
this.begin = begin;
this.end = end;
this.file = file;
this.url = url;
this.id = id;
}
@Override
public void run() {
try {
//判断是否下载完成
if (begin > end)
return;
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(500);
//设置需要下载的位置
connection.setRequestProperty("Range", "bytes=" + begin + "-" + end);
InputStream is = connection.getInputStream();
byte[] buff = new byte[1024 * 1024];
RandomAccessFile accessFile = new RandomAccessFile(file, "rw");
//设置写入文件的位置
accessFile.seek(begin);
int len = 0;
HashMap<String, Integer> map = threadList.get(id);
//开始下载
while ((len = is.read(buff)) != -1&&downLoading) {
accessFile.write(buff, 0, len);
//更新总下载进度
updateProgress(len);
//更新每段的下载进度
map.put("finished", map.get("finished") + len);
}
is.close();
accessFile.close();
} catch (IOException e) {
handler.sendEmptyMessage(1);
e.printStackTrace();
}
}
}
//更新总下载进度
synchronized private void updateProgress(int add) {
total += add;
handler.obtainMessage(0, total, 0).sendToTarget();
}
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0) {
//更新UI
progressBar.setProgress(msg.arg1/1024);
Log.e("长度:",msg.arg1+"");
if (msg.arg1 >= leanth)
Toast.makeText(MainActivity.this, "下载完成", Toast.LENGTH_SHORT).show();
} else if (msg.what == 1) {
Toast.makeText(MainActivity.this, "文件不存在", Toast.LENGTH_SHORT).show();
downLoading = false;
button.setText("开始");
}
}
};
}