• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > android --多线程下载过程分析

android --多线程下载过程分析

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android 多线程,android 多线程下载,android多线程机制,android多线程编程,android多线程实例等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

android --多线程下载过程分析


多线程下载文件的过程是:

(1)首先获得下载文件的长度,然后设置本地文件的长度。

HttpURLConnection.getContentLength();//获取下载文件的长度

RandomAccessFile file = new RandomAccessFile("QQSetup.exe","rwd");

file.setLength(filesize);//设置本地文件的长度

 

(2)根据文件长度和线程数计算每条线程下载的数据长度和下载位置。

如:文件的长度为6M,线程数为3,那么,每条线程下载的数据长度为2M,每条线程开始下载的位置如下图所示。

\

例如10M大小,使用3个线程来下载,

线程下载的数据长度 (10%3 == 0 ? 10/3:10/3+1) ,第1,2个线程下载长度是4M,第三个线程下载长度为2M

下载开始位置:线程id*每条线程下载的数据长度 = ?

下载结束位置:(线程id+1)*每条线程下载的数据长度-1=?

 

(3)使用Http的Range头字段指定每条线程从文件的什么位置开始下载,下载到什么位置为止,

如:指定从文件的2M位置开始下载,下载到位置(4M-1byte)为止

代码如下:HttpURLConnection.setRequestProperty("Range", "bytes=2097152-4194303");

 

(4)保存文件,使用RandomAccessFile类指定每条线程从本地文件的什么位置开始写入数据。

RandomAccessFilethreadfile= newRandomAccessFile("QQWubiSetup.exe ","rwd");

threadfile.seek(2097152);//从文件的什么位置开始写入数据

 

/** 
 *多线程下载,UI更新类  
 *@author young 
 * */  
public class MultiThreadDownload extends Thread{  
    private static final String TAG = "MultiThreadDownload";  
    /**每一个线程需要下载的大小 */  
    private int blockSize;  
    /*** 线程数量
 默认为5个线程下载*/  
    private int threadNum = 5;  
    /*** 文件大小 */  
    private int fileSize;  
    /** * 已经下载多少 */  
    private int downloadSize;  
    /**文件的url,线程编号,文件名称*/  
    private String UrlStr,ThreadNo,fileName;  
    /***保存的路径*/  
    private String savePath;  
    /**下载的百分比*/  
    private int downloadPercent = 0;  
    /**下载的 平均速度*/  
    private int downloadSpeed = 0;  
    /**下载用的时间*/  
    private int usedTime = 0;  
    /**当前时间*/  
    private long curTime;  
    /**是否已经下载完成*/  
    private boolean completed = false;  
    private Handler handler ;  
    /** 
     * 下载的构造函数   
     * @param url  请求下载的URL 
     * @param handler   UI更新使用 
     * @param savePath  保存文件的路径 
     */  
    public MultiThreadDownload(Handler handler,String url,String savePath)  
    {  
        this.handler = handler;  
        this.UrlStr = url;  
        this.savePath = savePath;  
        Log.e(TAG, toString());  
    }  
      
    @Override  
    public void run() {  
          
        FileDownloadThread[] fds = new FileDownloadThread[threadNum];//设置线程数量  
        try {  
            URL url = new URL(UrlStr);  
            URLConnection conn = url.openConnection();  
            fileSize = conn.getContentLength();  
              
            this.fileName = FileUtil.getFileName(UrlStr);  
            //只创建一个文件,saveFile下载内容  
            File saveFile = new File(savePath+"/"+fileName);  
            Log.e(TAG, "文件一共:"+fileSize+" savePath "+savePath+"  fileName  "+fileName);  
              
            RandomAccessFile accessFile = new RandomAccessFile(saveFile,"rwd");  
            //设置本地文件的长度和下载文件相同     
            accessFile.setLength(fileSize);    
            accessFile.close();  
            //Handler更新UI,发送消息  
            sendMsg(FileUtil.startDownloadMeg);  
            //每块线程下载数据  
            blockSize = ((fileSize%threadNum)==0)?(fileSize/threadNum):(fileSize/threadNum+1);  
            Log.e(TAG, "每个线程分别下载 :"+blockSize);  
              
            for (int i = 0; i < threadNum; i++) {  
                int curThreadEndPosition = (i+1)!=threadNum ? ((i+1)*blockSize-1) : fileSize;  
                FileDownloadThread fdt = new FileDownloadThread(url, saveFile, i*blockSize, curThreadEndPosition);  
                fdt.setName("thread"+i);  
                fdt.start();  
                fds[i]=fdt;  
            }  
            /** 
             * 获取数据,更新UI,直到所有下载线程都下载完成。 
             */  
            boolean finished = false;  
            //开始时间,放在循环外,求解的usedTime就是总时间  
            long startTime = System.currentTimeMillis();  
            while(!finished)  
            {  
                downloadSize = 0;  
                finished = true;  
                for (int i = 0; i < fds.length; i++) {  
                    downloadSize+= fds[i].getDownloadSize();  
                    if(!fds[i].isFinished())  
                    {  
                        finished = false;  
                    }  
                }  
                downloadPercent = (downloadSize*100)/fileSize;  
                curTime = System.currentTimeMillis();  
                System.out.println("curTime = "+curTime+" downloadSize = "+downloadSize+" usedTime "+(int) ((curTime-startTime)/1000));  
                usedTime = (int) ((curTime-startTime)/1000);  
                  
                if(usedTime==0)usedTime = 1;    
                downloadSpeed = (downloadSize/usedTime)/1024;  
                sleep(1000);/*1秒钟刷新一次界面*/  
                sendMsg(FileUtil.updateDownloadMeg);  
            }  
            Log.e(TAG, "下载完成");  
            completed = true;  
            sendMsg(FileUtil.endDownloadMeg);  
        } catch (Exception e) {  
            Log.e(TAG, "multi file error  Exception  "+e.getMessage());  
            e.printStackTrace();  
        }  
        super.run();  
    }  
    /** 
     * 得到文件的大小 
     * @return 
     */  
    public int getFileSize()  
    {  
        return this.fileSize;  
    }  
    /** 
     * 得到已经下载的数量 
     * @return 
     */  
    public int getDownloadSize()  
    {  
        return this.downloadSize;  
    }  
    /** 
     * 获取下载百分比 
     * @return 
     */  
    public int getDownloadPercent(){  
        return this.downloadPercent;  
    }  
   /** 
    * 获取下载速度 
    * @return 
    */  
    public int getDownloadSpeed(){  
        return this.downloadSpeed;  
    }  
    /** 
     * 修改默认线程数 
     * @param threadNum 
     */  
    public void setThreadNum(int threadNum){  
        this.threadNum = threadNum;  
    }  
    /** 
     * 分块下载完成的标志 
     * @return 
     */  
    public boolean isCompleted(){  
        return this.completed;  
    }  
    @Override  
    public String toString() {  
        return "MultiThreadDownload [threadNum=" + threadNum + ", fileSize="  
                + fileSize + ", UrlStr=" + UrlStr + ", ThreadNo=" + ThreadNo  
                + ", savePath=" + savePath + "]";  
    }  
      
    /** 
     * 发送消息,用户提示 
     * */  
    private void sendMsg(int what)  
    {  
        Message msg = new Message();  
        msg.what = what;  
        handler.sendMessage(msg);  
    } 
public class FileDownloadThread extends Thread{  
    private static final String TAG = "FileDownloadThread";  
    /**缓冲区 */  
    private static final int BUFF_SIZE = 1024;  
    /**需要下载的URL*/  
    private URL url;  
    /**缓存的FIle*/  
    private File file;  
    /**开始位置*/  
    private int startPosition;  
    /**结束位置*/  
    private int endPosition;  
    /**当前位置*/  
    private int curPosition;  
    /**完成*/  
    private boolean finished = false;  
    /**已经下载多少*/  
    private int downloadSize = 0;  
      
    /*** 
     * 分块文件下载,可以创建多线程模式 
     * @param url 



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • android 多线程断点续传视频列表
  • 转载 Android 多线程处理之多线程用法大集合,android大集合
  • android --多线程下载过程分析

相关文章

  • 2017-05-26Android--Dialog对话框
  • 2017-05-26android 获取GPS定位,androidgps定位
  • 2017-05-26配置adb环境变量,adb环境变量
  • 2017-05-26Android应用程序安装过程浅析
  • 2017-05-26android的color整理(一),androidcolor整理
  • 2017-05-26Android面试题--事件处理,android试题--事件
  • 2017-05-26android 4.2 系统以后的飞行模式,android4.2
  • 2017-05-26首页2--动态自定义圆形进度条,首页2--圆形进度条
  • 2017-05-26Android中使用开源框架EventBus3.0实现Fragment之间的通信交互,fragment开源框架
  • 2017-05-26Android 指纹认证,android指纹认证

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • MVP解析,mvp模式解析实践
    • SQLite 在 Android 的应用,sqliteandroid应用
    • 使用Eclipse开发Android源码
    • ButterKnife注解框架详解,butterknife注解框架
    • Android Studio Lambda Config,androidlambda
    • android插件开发-就是你了!启动吧!插件的activity(二)
    • Android项目使用Dagger2进行依赖注入
    • Android之RecyclerView的原生Bug-Inconsistency detected. Invalid view holder adapter positionViewHolder{a1bbfa3 position=2 id=-1, oldPos=-1, pLpos:-1 no parent},recyclerviewholder
    • 活动的生命周期系列(一)返回栈,生命周期系列
    • Android和JavaScript相互调用的方法,androidjavascript

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有