多线程断点下载(开始下载,暂停下载,百分比进度条)

  1. package cn.itcast.download;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.io.FileNotFoundException;  
  6. import java.io.FileOutputStream;  
  7. import java.io.IOException;  
  8. import java.io.InputStream;  
  9. import java.io.RandomAccessFile;  
  10. import java.net.HttpURLConnection;  
  11. import java.net.MalformedURLException;  
  12. import java.net.ProtocolException;  
  13. import java.net.URL;  
  14.   
  15. import cn.itcast.mutiledownload.StreamTool;  
  16.   
  17. import android.app.Activity;  
  18. import android.os.Bundle;  
  19. import android.os.Handler;  
  20. import android.os.Message;  
  21. import android.view.View;  
  22. import android.view.View.OnClickListener;  
  23. import android.widget.Button;  
  24. import android.widget.EditText;  
  25. import android.widget.ProgressBar;  
  26. import android.widget.TextView;  
  27. import android.widget.Toast;  
  28.   
  29. public class MutiledownloadActivity extends Activity implements OnClickListener {  
  30.   
  31.     private ProgressBar pb;  
  32.     private Button bt;  
  33.     private TextView tv;  
  34.     private EditText et;  
  35.     boolean flag = true;  
  36.     boolean stopflag = false;  
  37.     private Handler handler = new Handler() {  
  38.   
  39.         @Override  
  40.         public void handleMessage(Message msg) {  
  41.             pb.setProgress(total);  
  42.   
  43.             int max = pb.getMax();  
  44.             if (total >= (max - 1)) {  
  45.                 total = max;  
  46.                 flag = false;  
  47.             }  
  48.             int result = total * 100 / max;  
  49.             tv.setText("当前进度 :" + result + "%");  
  50.   
  51.             super.handleMessage(msg);  
  52.         }  
  53.     };  
  54.   
  55.     int total = 0;  
  56.   
  57.     @Override  
  58.     public void onCreate(Bundle savedInstanceState) {  
  59.         super.onCreate(savedInstanceState);  
  60.         setContentView(R.layout.main);  
  61.         pb = (ProgressBar) this.findViewById(R.id.pb);  
  62.         bt = (Button) this.findViewById(R.id.bt);  
  63.         tv = (TextView) this.findViewById(R.id.tv_process);  
  64.         et = (EditText) this.findViewById(R.id.et);  
  65.         bt.setOnClickListener(this);  
  66.   
  67.     }  
  68.   
  69.     @Override  
  70.     public void onClick(View v) {  
  71.         switch (v.getId()) {  
  72.         case R.id.bt:  
  73.             // 创建一个子线程 定期的更新ui  
  74.   
  75.             if("开始下载".equals(bt.getText().toString())){  
  76.                 bt.setText("暂停");  
  77.                 stopflag = false//开始下载   
  78.             }  
  79.             else {  
  80.                 bt.setText("开始下载");  
  81.                 stopflag = true;  
  82.             }  
  83.                 new Thread() {  
  84.   
  85.                     @Override  
  86.                     public void run() {  
  87.                         super.run();  
  88.                         while (flag) {  
  89.                             try {  
  90.                                 sleep(1000);  
  91.                                 // 如果total > = 文件长度  
  92.                                 Message msg = new Message();  
  93.                                 handler.sendMessage(msg);  
  94.                             } catch (InterruptedException e) {  
  95.                                 e.printStackTrace();  
  96.                             }  
  97.   
  98.                         }  
  99.                     }  
  100.                 }.start();  
  101.   
  102.                 // 开始执行下载的操作  
  103.                 String path = et.getText().toString().trim();  
  104.                 if ("".equals(path)) {  
  105.                     Toast.makeText(this"路径不能为空"1).show();  
  106.                     return;  
  107.                 }  
  108.                 try {  
  109.                     URL url = new URL(path);  
  110.                     HttpURLConnection conn = (HttpURLConnection) url  
  111.                             .openConnection();  
  112.                     conn.setRequestMethod("GET");  
  113.                     conn.setConnectTimeout(5000);  
  114.                     conn.setRequestProperty("User-Agent",  
  115.                             "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");  
  116.                     int code = conn.getResponseCode();  
  117.                     if (code == 200) {  
  118.                         int len = conn.getContentLength();  
  119.                         RandomAccessFile file = new RandomAccessFile(  
  120.                                 "/mnt/sdcard/" + getFilenName(path), "rwd");  
  121.                         // 1.设置本地文件大小跟服务器的文件大小一致  
  122.                         file.setLength(len);  
  123.                         // 设置进度条的最大值  
  124.                         pb.setMax(len);  
  125.   
  126.                         // 2 .假设开启3 个线程  
  127.                         int threadnumber = 3;  
  128.                         int blocksize = len / threadnumber;  
  129.                         /** 
  130.                          * 线程1 0~ blocksize 线程2 1*bolocksize ~ 2*blocksize 线程3 
  131.                          * 2*blocksize ~ 文件末尾 
  132.                          */  
  133.                         for (int i = 0; i < threadnumber; i++) {  
  134.                             int startposition = i * blocksize;  
  135.                             int endpositon = (i + 1) * blocksize;  
  136.                             if (i == (threadnumber - 1)) {  
  137.                                 // 最后一个线程  
  138.                                 endpositon = len;  
  139.                             }  
  140.   
  141.                             DownLoadTask task = new DownLoadTask(i, path,  
  142.                                     startposition, endpositon);  
  143.                             task.start();  
  144.                         }  
  145.   
  146.                     }  
  147.                 } catch (Exception e) {  
  148.                     Toast.makeText(this"下载出现异常"0).show();  
  149.                     e.printStackTrace();  
  150.                 }  
  151.               
  152.             break;  
  153.         }  
  154.   
  155.     }  
  156.   
  157.     class DownLoadTask extends Thread {  
  158.   
  159.         int threadid;  
  160.         String filepath;  
  161.         int startposition;  
  162.         int endpositon;  
  163.   
  164.         public DownLoadTask(int threadid, String filepath, int startposition,  
  165.                 int endpositon) {  
  166.             this.threadid = threadid;  
  167.             this.filepath = filepath;  
  168.             this.startposition = startposition;  
  169.             this.endpositon = endpositon;  
  170.   
  171.         }  
  172.   
  173.         @Override  
  174.         public void run() {  
  175.             try {  
  176.                 File postionfile = new File("/mnt/sdcard/" + threadid + ".txt");  
  177.                 URL url = new URL(filepath);  
  178.                 HttpURLConnection conn = (HttpURLConnection) url  
  179.                         .openConnection();  
  180.                 System.out.println("线程" + threadid + "正在下载 " + "开始位置 : "  
  181.                         + startposition + "结束位置 " + endpositon);  
  182.   
  183.                 if (postionfile.exists()) {  
  184.                     FileInputStream fis = new FileInputStream(postionfile);  
  185.                     byte[] result = StreamTool.getBytes(fis);  
  186.                     String str = new String(result);  
  187.                     if (!"".equals(str)) {  
  188.                         int newstartposition = Integer.parseInt(str);  
  189.                         if (newstartposition > startposition) {  
  190.                             startposition = newstartposition;  
  191.                         }  
  192.                     }  
  193.                 }  
  194.   
  195.                 // "Range", "bytes=2097152-4194303")  
  196.                 conn.setRequestProperty("Range""bytes=" + startposition + "-"  
  197.                         + endpositon);  
  198.                 conn.setRequestMethod("GET");  
  199.                 conn.setConnectTimeout(5000);  
  200.                 conn.setRequestProperty("User-Agent",  
  201.                         "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");  
  202.                 InputStream is = conn.getInputStream();  
  203.                 RandomAccessFile file = new RandomAccessFile("/mnt/sdcard/"  
  204.                         + getFilenName(filepath), "rwd");  
  205.                 // 设置 数据从文件哪个位置开始写  
  206.                 file.seek(startposition);  
  207.                 byte[] buffer = new byte[1024];  
  208.                 int len = 0;  
  209.                 // 代表当前读到的服务器数据的位置 ,同时这个值已经存储的文件的位置  
  210.                 int currentPostion = startposition;  
  211.                 // 创建一个文件对象 ,记录当前某个文件的下载位置  
  212.   
  213.                 while ((len = is.read(buffer)) != -1) {  
  214.                     if (stopflag) {  
  215.                         return;  
  216.                     }  
  217.                     file.write(buffer, 0, len);  
  218.   
  219.                     synchronized (MutiledownloadActivity.this) {  
  220.                         total += len;  
  221.                     }  
  222.   
  223.                     currentPostion += len;  
  224.                     // 需要把currentPostion 信息给持久化到存储设备  
  225.                     String position = currentPostion + "";  
  226.                     FileOutputStream fos = new FileOutputStream(postionfile);  
  227.                     fos.write(position.getBytes());  
  228.                     fos.flush();  
  229.                     fos.close();  
  230.                 }  
  231.   
  232.                 file.close();  
  233.                 System.out.println("线程" + threadid + "下载完毕");  
  234.                 // 当线程下载完毕后 把文件删除掉  
  235.                 if (postionfile.exists()) {  
  236.                     postionfile.delete();  
  237.                 }  
  238.   
  239.             } catch (Exception e) {  
  240.                 e.printStackTrace();  
  241.             }  
  242.   
  243.             super.run();  
  244.         }  
  245.   
  246.     }  
  247.   
  248.     public String getFilenName(String path) {  
  249.         int start = path.lastIndexOf("/") + 1;  
  250.         return path.substring(start, path.length());  
  251.     }  

  1. }  

转载地址http://blog.csdn.net/dacainiao007/article/details/8222779

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
注意事项: 1、主进程传入的对象或变量不管是不是ref线程内操作传入的引用都会影响主进程的对象或变量,且对象只能是nonvisualobject类型的。 2、基础变量如long等等都不能传引用ref会运行会报错 3、SharedObjectUnregister只是把SharedObjectDirectory中的去掉,实际内存不会释放必须destroy 4、主进程不能直接访问线程中的变量和对象,可以通过处理类私有的办法处理。 5、千万注意释放线程的时候一定要把线程里面的资源释放完,不然百分百卡死。比如一个线程里面有一个timing的计时器,如果不先stop(),直接destroy,百分百卡死。如果连接数据库或者其他接口时千万注意了!!!千万要在uf_stop()(此例子中的释放预留方法)里面把所有的资源都释放干净,资源都释放干净,源都释放干净,都释放干净,释放干净,放干净,干净,净…… 大体设计思路: 1、在主进程中建立一个“任务信息类”数组,其中包含“任务线程类”,一个任务对应一个线程。 2、在主进程中建立一个“任务管理类”,负责处理任务信息类。 简单举例: 1、新建1个“任务管理类”,再新建N“任务信息类”,将“任务信息类”赋值完成加入“任务管理类”,并创建一个“任务线程类”,此时线程开始running。 2、“任务线程类”中有一个内部timing类,监控自己是否执行完成,会改标志。“任务管理类”也有一个timing监控“任务信息类”和“任务线程类”的情况,把完成的结束。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值