android多线程下载
2016-12-29 14:55
218 查看
文章的开头奉送上代码,已方便大家对照学习。(因为电脑卡的原因,代码是用eclipse编写,给大家带来不便还请见谅。)
总体的实现思路就是这样的。下面来讲一下编码实现。
好了就讲到这里吧,在技术上我依旧是个小渣渣,加油,勉励自己!
1 前言
1.1多线程下载
APP更新的时候如果单线程下载的话相对来说是比较慢的。但是如果能把APK分成几段,分别用线程下载的话,就会快很多。接下来就来讲解一下多线程下载。1.2断点续传
多线程下载如果理解了,断点续传就好做多了。用数据库保存相关断点,继续下载就行,这里就不介绍了。2 实现思路
2.1 用到的核心知识点
1.RandomAccessFile 随机访问文件的读写。 2.BufferedInputStream缓冲流的读写。 3.URLConnection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);设置下载的起至段。
2.2 实现思路
1.启动服务service,在服务中启动线程请求地址,获取下载内容大小。 2.根据下载内容的大小分成3段,分成3个线程分别下载。 3.在每个线程中分成设置下载位置进行分别下载。 4.将下载下来的流利用RandomAccessFile写入文件。
总体的实现思路就是这样的。下面来讲一下编码实现。
3 代码实现
3.1 启动服务
Intent intent = new Intent("com.action.downloadservice"); startService(intent);
3.2 DownLoadService类的代码
/** * @author 作者 YYD * @version 创建时间:2016年12月28日 下午1:59:07 * @function 未添加 */ @SuppressLint("NewApi") public class DownLoadService extends Service implements Callback { private Handler handler = new Handler(this); private int allFileLength = 0;//软件总大小 private int currentFileLenght = 0;//当前下载的数量 private long preDownLoadTime = 0;//下载前的时间记录 private int ThreadNum = 3;//线程数 @Override public void onCreate() { super.onCreate(); preDownLoadTime = System.currentTimeMillis(); mulitDownload(); } @Override public IBinder onBind(Intent intent) { return null; } /** *这个是handler用于计算3个线程下在的总进度, *如果(下载的大小==总内容长度)说明下载完了。 */ @Override public boolean handleMessage(Message msg) { switch (msg.what) { case 1000: int num = msg.arg1; currentFileLenght += num; if(currentFileLenght == allFileLength){ Log.d("refreshlistview", "下载完毕!"+"消耗时间:"+((System.currentTimeMillis() - preDownLoadTime)/1000)); } break; } return false; } /** * 多线程下载 * 这个是核心代码,思路如下: * 1.线程请求网络,获取内容长度。 * 2.根据下载内容长度,分3段,分3个线程分别下载。 * 比如:现在长度是1534。 * 第一段是:0 ~ 1500/3*1 - 1 * 第二段是:1500/3*1 ~ 1500/3*2 - 1 * 第三段是:1500/3*2 ~ 1534 * 这就是for循环中的逻辑,用for循环分别启动3个线程来下载这3段。 */ private void mulitDownload() { new Thread(new Runnable() { @Override public void run() { try { URL url = new URL(UrlManager.url); URLConnection connection = url.openConnection(); allFileLength = connection.getContentLength();// 获取内容的长度 File file = new File( Environment.getExternalStorageDirectory(), "gaoyipin.apk"); if (!file.exists()) { boolean isCreate = file.createNewFile(); } DownLoadThread[] threads = new DownLoadThread[ThreadNum];// 用于管理下载线程 for (int i = 0; i < ThreadNum; i++) { DownLoadThread thread = null; if (i == (ThreadNum -1)) { thread = new DownLoadThread(allFileLength / ThreadNum * (ThreadNum-1), allFileLength, file, handler, i); } else { thread = new DownLoadThread(allFileLength / ThreadNum * i, allFileLength / ThreadNum * (i + 1) - 1, file, handler, i); } thread.start(); threads[i] = thread; } } catch (Exception e) { Log.d("refreshlistview", "下载前异常"); } } }).start(); } @Override public void onDestroy() { super.onDestroy(); Log.d("refreshlistview", "服务停止"); } }
3.3 DownLoadThread类的代码
/** * @author 作者 YYD * @version 创建时间:2016年12月28日 下午2:06:00 * @function 未添加 */ public class DownLoadThread extends Thread { private int process = 0; private int startPos = 0;//开始下载位置 private int endPos = 0;//结尾下载的进度 private File downLoadFile;//要下载的文件 private Handler handler ; public DownLoadThread(int startPos, int endPos, File downLoadFile,Handler handler,int threadId) { super(""+threadId); this.startPos = startPos; this.endPos = endPos; this.downLoadFile = downLoadFile; this.handler = handler; Log.d("refreshlistview", "startPos:"+startPos+" endPos: "+endPos); } @Override public void run() { super.run(); try { URL url = new URL(UrlManager.url); URLConnection connection = url.openConnection(); connection.setAllowUserInteraction(true); connection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos); InputStream is = connection.getInputStream(); RandomAccessFile raf = new RandomAccessFile( downLoadFile.getAbsolutePath(), "rw");// 随机访问文件的读写,第一个参数是文件的路径 raf.seek(startPos); BufferedInputStream bis = new BufferedInputStream(is); byte[] buffer = new byte[2048]; int writeNum = -1; while ((writeNum = bis.read(buffer))> 0) { raf.write(buffer,0,writeNum); Message msg = new Message(); msg.what = 1000; msg.arg1 = writeNum; handler.sendMessage(msg); process += writeNum; } Log.d("refreshlistview", "线程"+getName()+"下载完毕"); raf.close(); bis.close(); is.close(); } catch (Exception e) { Log.d("refreshlistview", "线程"+getName()+"下载异常:"+e.toString()); } } }
4 结尾
文章的最后奉送上代码,方便大家对照学习。好了就讲到这里吧,在技术上我依旧是个小渣渣,加油,勉励自己!
相关文章推荐
- android多线程下载以及断点续传
- android 多线程下载
- Android中多线程下载
- Android开发_使用HttpURLConnection实现多线程下载
- android HTTP实现文件多线程下载
- android 多线程下载 支持断点续传的工具类
- Android中多线程下载
- Android http 多线程下载
- android HttpURLConnection实现多线程下载
- [转]Android:使用URL和URLConnection(多线程下载)
- android 客户端多线程下载
- Android通过HTTP协议实现多线程下载
- android实现多线程下载
- android 多线程下载 显示进度 速度
- Android中级篇之多线程下载
- Android 多线程下载
- Android中多线程下载方面的知识点
- Android开发(23)--java中的多线程下载
- Android之 多线程下载、断点续传 实现
- android实现多线程下载