首页 > 代码库 > 33、多线程断点下载的实现&界面的更新
33、多线程断点下载的实现&界面的更新
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 <EditText13 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 <ProgressBar20 android:id="@+id/pb"21 style="?android:attr/progressBarStyleHorizontal"22 android:layout_width="fill_parent"23 android:layout_height="wrap_content" />24 25 <TextView26 android:id="@+id/tv_process"27 android:layout_width="fill_parent"28 android:layout_height="wrap_content" />29 30 <Button31 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 线程3105 * 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 @Override148 public void run() {149 try {150 File postionfile = new File("/mnt/sdcard/" + threadid + ".txt");151 URL url = new URL(filepath);152 HttpURLConnection conn = (HttpURLConnection) url153 .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"/>
33、多线程断点下载的实现&界面的更新
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。