栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

Android实现多线程断点下载的方法

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android实现多线程断点下载的方法

本文实例讲述了Android实现多线程断点下载的方法。分享给大家供大家参考。具体实现方法如下:

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; 
      
     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()); 
  } 
}

希望本文所述对大家的Android程序设计有所帮助。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/164352.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号