Android第九讲——网络(四) 文件的下载(单线程下载、多线程下载)
来源:互联网 发布:程序员的逻辑题 编辑:程序博客网 时间:2024/05/20 20:45
我们学习了连接网络与服务器后不只是仅仅上一些网页,与服务器进行交流。我们还可以从网上下载文件(Download)
文件的下载分为多种:
1.单线程下载
2.多线程下载
3.多线程断点续传
单线程下载
首先我们来看单线程下载:
文件的下载需要时间的,所以文件的Download属于耗时操作,故而不能将它放在UI主线程中,也是需要Handler或者异步线程(AsyncTask)
本次为AsyncTask
1.首先显示连接服务器。
2.通过GetContentLength获取要下载的文件的长度。
3.得到输入流,用来读取文件。
4.创建文件名
5.通过FileOutputStream(file)向创建的文件中写入下载的文件
6.UI主线程调用异步线程
/** * 单线程下载的线程 */ class DownLoadSingleTask extends AsyncTask<String,Integer,String>{ @Override protected String doInBackground(String... params) { try { URL url = new URL("http://192.168.***.**:8080/HTTpTest_Servelet/music/SetMeFree.mp3"); URLConnection connection = url.openConnection(); int length =connection.getContentLength();//获取内容的长度 InputStream is = connection.getInputStream(); File file = new File(Environment.getExternalStorageDirectory(),"Set Me Free.mp3");//创建文件夹 if (!file.exists()){ file.createNewFile(); } FileOutputStream fos = new FileOutputStream(file); byte[] array = new byte[1024];//缓存区,用于缓存读取的数据 int i = is.read(array); int sum = 0; while (i!=-1){ fos.write(array); sum += i; publishProgress(length,sum); i = is.read(array); } fos.flush(); fos.close(); is.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; }
在UI主线程中调用AsyncTask
case R.id.button_download_single: DownLoadSingleTask task = new DownLoadSingleTask(); task.execute(); break;
多线程下载
有时文件较大,用一个线程下载文件时会消耗很多时间,通过多线程能够缩短文件下载的时间。
多线程的工作流程:(三线程的)
多线程下载:用for循环创建多个线程
打开网络连接—>得到数据长度—>长度除以线程数—>写入文件
connection.setRequestProperty(“Range”, “bytes=” + start + “-” + end);//设置头信息的,比如格式,UA等,不设置自然有默认的,一般的请求倒不需要去设置,可以去看看android里的DefaultHttpClient里也有设置头信息的
RandomAccessFile (文件路径,”rw”)
seek(start) 之后再写文件
1.主线程调一个线程为了用来连接网络(服务器)
2.单独写一个线程,用来多线程下载。主要有文件地址url,每个线程下载的起始位置start,每个线程下载的末尾位置end,下载后的文件File
/** * 多线程下载的线程 * Created by Went_Gone on 2015/9/12. */public class MulitDownloadThread extends Thread{ private int start; private int end; private String urlPath; private File file; private int sum; public int getSum() { return sum; } public MulitDownloadThread( int start, int end, String urlPath, File file) { this.start = start; this.end = end; this.urlPath = urlPath; this.file = file; } @Override public void run() { try { URL url = new URL(urlPath); URLConnection connection = url.openConnection(); connection.setAllowUserInteraction(true); connection.setRequestProperty("Range", "bytes=" + start + "-" + end);//设置头信息的,比如格式,UA等,不设置自然有默认的,一般的请求倒不需要去设置,可以去看看android里的DefaultHttpClient里也有设置头信息的 InputStream is = connection.getInputStream(); RandomAccessFile raf = new RandomAccessFile(file.getAbsolutePath(),"rw");//随机访问文件的读写,第一个参数是文件的路径 raf.seek(start); byte[] array = new byte[1024]; int index = is.read(array); while (index!=-1){ raf.write(array,0,index); sum+=index; index = is.read(array); } Log.d("Mulit",this.getName()+" "+sum+"");//用来检验是不是多线程下载 raf.close(); is.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }}
在Activity中。
/** * 多线程下载 */ private void MulitDownload() { new Thread(new Runnable() { @Override public void run() { try { String urlPath = "http://192.168.***.*:8080/HTTpTest_Servelet/music/SetMeFree.mp3";// String urlPath = "http://img1.cache.netease.com/catchpic/6/6C/6C1F6740B3ECD7CC23C9E70B0C04B6C0.jpg";// String urlPath = "http://p.gdown.baidu.com/a7171b404c2b222af1cb5a3eca249e36e4ffb41e33c741e8fee67227b09cfd84cf4d133189ea79f032759a367b6d3dda9658d02aae07f2b8dc82b1c2c1169460e528cbd7742a45f9e7fe69eb61959bf3e9e537b5cb5f221b49366ca7af9d625ec9b0d991e96240723ddbfad0177b32ae8ab3c4903216bf582093102d7e6c0d3e78658f3a92c078ffe4dc7ed9e29a20192eba2f785430ca3b4c7b695578dd010ad7fcc6499ee3cfa2bed4d0ba07edaa1097957a4a96ee7e397976dc6060f9902ee34f85506a484274"; URL url = new URL(urlPath); URLConnection connection = url.openConnection(); length =connection.getContentLength();//获取内容的长度 File file = new File(Environment.getExternalStorageDirectory(),"Set Me Free aa.mp3");// File file = new File(Environment.getExternalStorageDirectory(),"tanyan.jpg");// File file = new File(Environment.getExternalStorageDirectory(),"QQyinyue.apk"); if (!file.exists()){ file.createNewFile(); } MulitDownloadThread[] threads = new MulitDownloadThread[3];//用于管理下载线程 for (int i = 0;i<3;i++) { MulitDownloadThread thread = null; if (i==2){ thread = new MulitDownloadThread(length / 3 * 2, length, urlPath, file); }else { thread = new MulitDownloadThread(length / 3 * i, length / 3 * (i + 1)-1, urlPath, file); } thread.start(); threads[i] = thread; } boolean isFinish = true; int sum = 0; while (isFinish){ for (MulitDownloadThread thread:threads) { sum += thread.getSum(); } Message msg = handler.obtainMessage(); msg.what = MULITE; msg.arg1 = sum; handler.sendMessage(msg); if (sum==length){ isFinish = false; } Thread.sleep(200); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); }
UI主线程中不能使用其他线程控制View,这里用Handler
private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what){ case MULITE: mProgressBar.setProgress((int) (msg.arg1*100.0/length)); break; } } };
- Android第九讲——网络(四) 文件的下载(单线程下载、多线程下载)
- 网络连接——文件下载(单线程/多线程)
- Android 单线程下载与多线程下载
- Android之单线程下载与多线程下载
- Android——单、多线程下载
- URLConnection,单线程下载,多线程下载
- 单线程下载和多线程下载
- 单线程下载和多线程下载
- Android 文件下载--普通单线程下载文件
- 多线程下载网络文件
- 网络下载编程的单文件多线程下载和断电续传
- Android实现单线程异步多文件下载的代码
- Android实现单线程异步多文件下载的代码
- Android 实现文件的单线程断点续传下载
- Android实现网络多线程文件下载
- Android实现网络多线程文件下载
- Android实现网络多线程文件下载
- Android实现网络多线程文件下载
- JSP 9大内置对象
- JVM系列文章(四):类加载机制
- 产品设计:Android应用-开发技术【数据缓存】
- ArchLinux安装教程
- JSP九大对象:内置对象
- Android第九讲——网络(四) 文件的下载(单线程下载、多线程下载)
- caffe安装遇到的问题总结
- 自定义View
- Supermarket 并查集
- JVM系列文章(五):Javac编译与JIT编译
- 学习OC有感而发
- uva 11549 Calculator Conundrum 周期,哇!这也能过
- 开篇 奋斗
- 关于caffe安装中的一些小问题