- package cn.itcast.download;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.RandomAccessFile;
- import java.net.HttpURLConnection;
- import java.net.MalformedURLException;
- import java.net.ProtocolException;
- import java.net.URL;
- import cn.itcast.mutiledownload.StreamTool;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.ProgressBar;
- import android.widget.TextView;
- import android.widget.Toast;
- public class MutiledownloadActivity extends Activity implements OnClickListener {
- private ProgressBar pb;
- private Button bt;
- private TextView tv;
- private EditText et;
- boolean flag = true;
- boolean stopflag = false;
- private Handler handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- pb.setProgress(total);
- int max = pb.getMax();
- if (total >= (max - 1)) {
- total = max;
- flag = false;
- }
- int result = total * 100 / max;
- tv.setText("当前进度 :" + result + "%");
- super.handleMessage(msg);
- }
- };
- int total = 0;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- pb = (ProgressBar) this.findViewById(R.id.pb);
- bt = (Button) this.findViewById(R.id.bt);
- tv = (TextView) this.findViewById(R.id.tv_process);
- et = (EditText) this.findViewById(R.id.et);
- bt.setOnClickListener(this);
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.bt:
- // 创建一个子线程 定期的更新ui
- if("开始下载".equals(bt.getText().toString())){
- bt.setText("暂停");
- stopflag = false; //开始下载
- }
- else {
- bt.setText("开始下载");
- stopflag = true;
- }
- new Thread() {
- @Override
- public void run() {
- super.run();
- while (flag) {
- try {
- sleep(1000);
- // 如果total > = 文件长度
- Message msg = new Message();
- handler.sendMessage(msg);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }.start();
- // 开始执行下载的操作
- String path = et.getText().toString().trim();
- if ("".equals(path)) {
- Toast.makeText(this, "路径不能为空", 1).show();
- return;
- }
- try {
- URL url = new URL(path);
- HttpURLConnection conn = (HttpURLConnection) url
- .openConnection();
- conn.setRequestMethod("GET");
- conn.setConnectTimeout(5000);
- conn.setRequestProperty("User-Agent",
- "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
- int code = conn.getResponseCode();
- if (code == 200) {
- int len = conn.getContentLength();
- RandomAccessFile file = new RandomAccessFile(
- "/mnt/sdcard/" + getFilenName(path), "rwd");
- // 1.设置本地文件大小跟服务器的文件大小一致
- file.setLength(len);
- // 设置进度条的最大值
- pb.setMax(len);
- // 2 .假设开启3 个线程
- int threadnumber = 3;
- int blocksize = len / threadnumber;
- /**
- * 线程1 0~ blocksize 线程2 1*bolocksize ~ 2*blocksize 线程3
- * 2*blocksize ~ 文件末尾
- */
- for (int i = 0; i < threadnumber; i++) {
- int startposition = i * blocksize;
- int endpositon = (i + 1) * blocksize;
- if (i == (threadnumber - 1)) {
- // 最后一个线程
- endpositon = len;
- }
- DownLoadTask task = new DownLoadTask(i, path,
- startposition, endpositon);
- task.start();
- }
- }
- } catch (Exception e) {
- Toast.makeText(this, "下载出现异常", 0).show();
- e.printStackTrace();
- }
- break;
- }
- }
- class DownLoadTask extends Thread {
- int threadid;
- String filepath;
- int startposition;
- int endpositon;
- public DownLoadTask(int threadid, String filepath, int startposition,
- int endpositon) {
- this.threadid = threadid;
- this.filepath = filepath;
- this.startposition = startposition;
- this.endpositon = endpositon;
- }
- @Override
- public void run() {
- try {
- File postionfile = new File("/mnt/sdcard/" + threadid + ".txt");
- URL url = new URL(filepath);
- HttpURLConnection conn = (HttpURLConnection) url
- .openConnection();
- System.out.println("线程" + threadid + "正在下载 " + "开始位置 : "
- + startposition + "结束位置 " + endpositon);
- if (postionfile.exists()) {
- FileInputStream fis = new FileInputStream(postionfile);
- byte[] result = StreamTool.getBytes(fis);
- String str = new String(result);
- if (!"".equals(str)) {
- int newstartposition = Integer.parseInt(str);
- if (newstartposition > startposition) {
- startposition = newstartposition;
- }
- }
- }
- // "Range", "bytes=2097152-4194303")
- conn.setRequestProperty("Range", "bytes=" + startposition + "-"
- + endpositon);
- conn.setRequestMethod("GET");
- conn.setConnectTimeout(5000);
- conn.setRequestProperty("User-Agent",
- "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
- InputStream is = conn.getInputStream();
- RandomAccessFile file = new RandomAccessFile("/mnt/sdcard/"
- + getFilenName(filepath), "rwd");
- // 设置 数据从文件哪个位置开始写
- file.seek(startposition);
- byte[] buffer = new byte[1024];
- int len = 0;
- // 代表当前读到的服务器数据的位置 ,同时这个值已经存储的文件的位置
- int currentPostion = startposition;
- // 创建一个文件对象 ,记录当前某个文件的下载位置
- while ((len = is.read(buffer)) != -1) {
- if (stopflag) {
- return;
- }
- file.write(buffer, 0, len);
- synchronized (MutiledownloadActivity.this) {
- total += len;
- }
- currentPostion += len;
- // 需要把currentPostion 信息给持久化到存储设备
- String position = currentPostion + "";
- FileOutputStream fos = new FileOutputStream(postionfile);
- fos.write(position.getBytes());
- fos.flush();
- fos.close();
- }
- file.close();
- System.out.println("线程" + threadid + "下载完毕");
- // 当线程下载完毕后 把文件删除掉
- if (postionfile.exists()) {
- postionfile.delete();
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- super.run();
- }
- }
- public String getFilenName(String path) {
- int start = path.lastIndexOf("/") + 1;
- return path.substring(start, path.length());
- }
- }
转载地址http://blog.csdn.net/dacainiao007/article/details/8222779