您当前的位置: 首页 > 

xiangzhihong8

暂无认证

  • 4浏览

    0关注

    1324博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

多线程下载

xiangzhihong8 发布时间:2014-02-27 21:17:10 ,浏览量:4

楼主三年磨剑(当然不是磨着一把剑),倾血奉献Android多线程下载Demo。有的人就问了“怎么写来写去还是Demo?”,因为老哥我实在太忙了, 每天写一点,写到现在也才写了个下载器,也就差下载管理类就是个完整的模块了。对于新手学习这已经足够了,不对,是完全足够了。

这不仅仅只是一个简单的Demo,这绝对是你前所未见的商业级别的范例,集支持多线程下载,断点续传,只使用wifi网络下载,显示下载速度,人性化提示 及超强的容错机制多功能于一体,绝对的实用,绝对的专业。

当然我写这个是为了下载apk的,大家稍微改一改就可以写成更通用的下载器。唯一有点不足的地方就是在Android上使用RandomAccessFile在创建大文件的时候 速度有些慢,导致前几秒的进度都为0。不知道有没有人可以帮我解决这个问题。

下面给出关键代码。

[java]  view plain copy
  1. package com.h3c.DownloadEngine;  
  2.   
  3. import java.io.File;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.RandomAccessFile;  
  7. import java.net.HttpURLConnection;  
  8. import java.net.URL;  
  9. import java.util.ArrayList;  
  10.   
  11. import android.content.Context;  
  12. import android.os.Environment;  
  13. import android.util.Log;  
  14.   
  15. import com.h3c.DownloadEngine.common.DownloaderErrorException;  
  16. import com.h3c.DownloadEngine.common.EngineConstants;  
  17. import com.h3c.DownloadEngine.common.EngineUtil;  
  18. import com.h3c.DownloadEngine.common.EngineVariable;  
  19. import com.h3c.DownloadEngine.db.EngineDBOperator;  
  20. import com.h3c.DownloadEngine.entity.DownloadBean;  
  21.   
  22. public class Downloader {  
  23.     private final static String TAG = "Downloader";  
  24.     private final static byte[] lock_getFileSize = new byte[1];  
  25.     private final static byte[] lock_refresh_progress = new byte[1];  
  26.   
  27.     private int mThreadCount = 4;// 默认子线程数为4个  
  28.     private int bufferSize = 1024 * 16; // 16K 一个块  
  29.   
  30.     private DownloadBean mBean;// 注意,这里是dwonloader的bean不是其subBean  
  31.     private Context mContext;  
  32.     private DownloadEngineCallback mCallback;  
  33.     private EngineDBOperator mDBOper;  
  34.     private int mDoneThreadCount = 0;// 完成的线程数  
  35.     private int mState = EngineConstants.DOWNLOAD_STATE_INIT;// 下载器状态  
  36.     private ArrayList mBeans = new ArrayList(  
  37.             mThreadCount);  
  38.   
  39.     public Downloader(DownloadBean bean, Context context,  
  40.             DownloadEngineCallback callback) throws DownloaderErrorException {  
  41.         this.mBean = bean;  
  42.         this.mContext = context;  
  43.         this.mCallback = callback;  
  44.         this.mDBOper = EngineDBOperator.getInstance(context);  
  45.   
  46.         if (this.mDBOper != null) {  
  47.             if (this.mDBOper.isHasDownloadTaskByUrl(bean.url)) {// 如果此任务已经存放进数据库  
  48.                 getDownloaderInfoFromDB(bean);  
  49.             } else {// 插入信息至数据库  
  50.                 addDownloaderInfoToDB(bean);  
  51.             }  
  52.         } else {  
  53.             callBackError("Downloader错误,可能是EngineDBOperator为Null.");  
  54.             throw new DownloaderErrorException(  
  55.                     "Downloader错误,可能是EngineDBOperator为Null.");  
  56.         }  
  57.     }  
  58.   
  59.     public DownloadBean getDownloaderInfo() {  
  60.         return mBean;  
  61.     }  
  62.   
  63.     public int getDownloaderState() {  
  64.         return mState;  
  65.     }  
  66.   
  67.     /** 
  68.      * 请求初始化 
  69.      *  
  70.      * @param state 
  71.      */  
  72.     protected void setDownloaderState(int state) {  
  73.         mState = state;  
  74.         if (state == EngineConstants.DOWNLOAD_STATE_INIT) {  
  75.             mBean.currentPosition = 0;  
  76.         }  
  77.     }  
  78.   
  79.     /** 
  80.      * 加入下载信息进入数据库,此方法用于刚刚初始化Downloader,且数据库中没有该任务的时候 
  81.      *  
  82.      * @param bean 
  83.      * @throws DownloaderErrorException 
  84.      */  
  85.     private void addDownloaderInfoToDB(DownloadBean bean)  
  86.             throws DownloaderErrorException {  
  87.         if (mState != EngineConstants.DOWNLOAD_STATE_INIT  
  88.                 && mState != EngineConstants.DOWNLOAD_STATE_STOP  
  89.                 && mState != EngineConstants.DOWNLOAD_STATE_ERROR) {  
  90.             callBackError("这个任务已经加入到数据库中了");  
  91.             throw new DownloaderErrorException("这个任务已经加入到数据库中了");  
  92.         }  
  93.   
  94.         if (mDBOper != null) {  
  95.             long fileSize = bean.fileSize;  
  96.             if (mBeans.size() > 0) {  
  97.                 mBeans.clear();  
  98.             }  
  99.   
  100.             try {  
  101.                 if (fileSize > 0) {// 判断传入的fileSize大小,如果大于0,就不用从网络中获取,直接初始化N个子下载器  
  102.                     if (!hasSpaceInSDCard()) {  
  103.                         return;  
  104.                     }  
  105.                     long range = fileSize / mThreadCount;// 文件分段值  
  106.                     for (int i = 0; i  mBean.fileSize) {  
  107.                     mBean.fileSize = subBean.fileSize;  
  108.                 }  
  109.             }  
  110.   
  111.             if (mBean.fileSize 
关注
打赏
1482932726
查看更多评论
立即登录/注册

微信扫码登录

0.0625s