android多线程下载
来源:互联网 发布:mac如何截屏快捷键 编辑:程序博客网 时间:2024/06/16 05:54
使用单线程下载文件会比较慢,如果使用n个线程,那么时间就会缩短为1/n,每个线程只下载其中的一段,都下载完以后再把这n段拼接起来就ok了。下面简单介绍一下多线程下载的原理和实现。
多线程下载的关键是怎样从服务器只获取文件的一部分,而不是整个文件。这里需要设置request header的一个属性:Range。
conn.setRequestProperty("Range", "bytes=" + start + "-" + end);
还有下载完毕后怎么把多个文件片段合并到一起的问题。可以使用RandomAccessFile,但要注意:每个线程需要建自己的RandomAccessFile对象,它们可以共同操作一个File,但不能使用同一个RandomAccessFile。
完整代码:
public class MainActivity extends ActionBarActivity { public static final String TEST_URL = "http://gdown.baidu.com/data/wisegame/e59f42264a98b05e/WeChat_861.apk"; private TextView[] tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv1 = (TextView) findViewById(R.id.tv1); TextView tv2 = (TextView) findViewById(R.id.tv2); TextView tv3 = (TextView) findViewById(R.id.tv3); tv = new TextView[3]; tv[0] = tv1; tv[1] = tv2; tv[2] = tv3; findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new Thread() { @Override public void run() { try { URL url = new URL(TEST_URL); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5000); conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)"); String fileName = TEST_URL.substring(TEST_URL.lastIndexOf("/") + 1); File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), fileName); int totalLength = conn.getContentLength(); int subLength = totalLength / 3; for(int i = 0; i < 3; i++){ int start = i * subLength; int end = (i+1) * subLength - 1; if(i == 2){ end = totalLength; } new DownloadThread(i, start, end, file, url).start(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }.start(); } }); } class DownloadThread extends Thread{ int threadId; int start; int end; File file; URL url; int currLength = 0; int totalLength; public DownloadThread(int threadId, int start, int end, File file, URL url){ this.threadId = threadId; this.start = start; this.end = end; this.file = file; this.url = url; totalLength = end - start + 1; } @Override public void run() { try { HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)"); conn.setRequestProperty("Range", "bytes=" + start + "-" + end); RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw"); randomAccessFile.seek(start); InputStream is = conn.getInputStream(); byte[] buf = new byte[4 * 1024]; int len; while((len = is.read(buf)) != -1){ currLength += len; runOnUiThread(new Runnable() { @Override public void run() { tv[threadId].setText("进程" + (threadId + 1) + " 下载进度:" + currLength + "/" + totalLength); } }); randomAccessFile.write(buf, 0, len); } is.close(); randomAccessFile.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }}
0 0
- Android -- 多线程下载, 断点下载
- Android断点下载,多线程下载
- android 多线程下载
- Android 多线程文件下载
- android多线程断点下载
- Android 多线程下载
- Android 多线程下载
- android多线程下载详解
- android多线程下载详解
- android多线程下载详解
- android多线程下载详解
- android多线程下载图片
- android多线程下载
- Android学习 多线程 下载
- android 多线程断点续传下载
- android多线程下载器
- android 多线程断点下载
- android实现多线程下载
- spring mvc EL ModelAndView的 Model 值 在jsp中不显示
- windows 网络问题
- Struts2学习笔记一(运行流程及自定义类型转换)
- java生成二维码使用QRCode和ZXing两种方式
- 简单的侧滑菜单实现
- android多线程下载
- freeBSD TAILQ队列的理解
- 支付宝可以休矣,淘宝才是阿里社交的正确选择
- UVA 10163 Storage Keepers
- fmt包的占位符
- adapter实例
- mongodb分片+集群
- 遍历字符串 返回字符重复出现的次数
- 【NOIP 2011】 选择客栈