1 <?xml version="1.0" encoding="utf-8"?>  2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  3  android:layout_width="fill_parent"  4  android:layout_height="fill_parent"  5  android:orientation="vertical" >  6  7 <TextView  8 android:layout_width="fill_parent"  9  android:layout_height="wrap_content" 10  android:text="@string/down_load" /> 11 12 <EditText 13 android:id="@+id/et" 14  android:layout_width="fill_parent" 15  android:layout_height="wrap_content" 16  android:hint="@string/hint" 17  android:text="http://192.168.1.247:8080/youdao.exe" /> 18 19 <ProgressBar 20 android:id="@+id/pb" 21  style="?android:attr/progressBarStyleHorizontal" 22  android:layout_width="fill_parent" 23  android:layout_height="wrap_content" /> 24 25 <TextView 26 android:id="@+id/tv_process" 27  android:layout_width="fill_parent" 28  android:layout_height="wrap_content" /> 29 30 <Button 31 android:id="@+id/bt" 32  android:layout_width="fill_parent" 33  android:layout_height="wrap_content" 34  android:text="@string/download" /> 35 36 </LinearLayout>

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

 1 public class StreamTool {  2 /**  3  * 把一个inputstream里面的内容转化成一个byte[]  4 */  5 public static byte[] getBytes(InputStream is) throws Exception{  6 ByteArrayOutputStream bos = new ByteArrayOutputStream();  7 byte[] buffer = new byte[1024];  8 int len = 0;  9 while((len = is.read(buffer))!=-1){ 10 bos.write(buffer, 0, len); 11  } 12  is.close(); 13  bos.flush(); 14 byte[] result = bos.toByteArray(); 15 System.out.println(new String(result)); 16 return result; 17  } 18 }

1 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> 2 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 3 <uses-permission android:name="android.permission.INTERNET"/>

更多相关文章

  1. Android中自定义滑动条风格
  2. android anr导出崩溃文件
  3. Android中的高效率的数据库操作框架----LitePal
  4. Android文件目录选择器(可自行扩展)
  5. Android解析自定义xml文件--Sax解析xml文件,测试demo(方案二)
  6. Android(安卓)AsyncTask
  7. android调用系统的相机服务
  8. Android删除指定文件夹下所有、删除指定文件夹和里边所有内容
  9. Android(安卓)init.rc文件解析过程详解(二)

随机推荐

  1. Android 数据库简单操作
  2. Android缓存理解
  3. Android(安卓)frameworks中Bn*和Bp*的区
  4. Android系统启动流程 -- android
  5. Android笔记-2
  6. 配置并使用Android支持的库
  7. Android(安卓)向系统发送一条短信
  8. 理解 Android 消息机制
  9. Android 修改横屏角度为顺时针270度
  10. 【Android】注解框架(三)-- 编译时注解,手写