您的位置:首页 > 移动开发 > Android开发

实现多线程下载(android)

2013-11-04 22:51 507 查看
DownUtil.java:

package org.xxx.net;

import java.io.InputStream;

import java.io.RandomAccessFile;

import java.net.HttpURLConnection;

import java.net.URL;

public class DownUtil

{

    // 定义下载资源的路径

    private String path;

    // 指定所下载的文件的保存位置

    private String targetFile;

    // 定义需要使用多少线程下载资源

    private int threadNum;

    // 定义下载的线程对象

    private DownloadThread[] threads;

    // 定义下载的文件的总大小

    private int fileSize;

    public DownUtil(String path, String targetFile, int threadNum)

    {

        this.path = path;

        this.threadNum = threadNum;

        // 初始化threads数组

        threads = new DownloadThread[threadNum];

        this.targetFile = targetFile;

    }

    public void download() throws Exception

    {

        URL url = new URL(path);

        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        conn.setConnectTimeout(5 * 1000);

        conn.setRequestMethod("GET");

        conn.setRequestProperty(

            "Accept",

            "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint,
application/msword, */*");

        conn.setRequestProperty("Accept-Language", "zh-CN");

        conn.setRequestProperty("Charset", "UTF-8");

        conn.setRequestProperty(

            "User-Agent",

            "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");

        conn.setRequestProperty("Connection", "Keep-Alive");

        // 得到文件大小

        fileSize = conn.getContentLength();

        conn.disconnect();

        int currentPartSize = fileSize / threadNum + 1;

        RandomAccessFile file = new RandomAccessFile(targetFile, "rw");

        // 设置本地文件的大小

        file.setLength(fileSize);

        file.close();

        for (int i = 0; i < threadNum; i++)

        {

            // 计算每条线程的下载的开始位置

            int startPos = i * currentPartSize;

            // 每个线程使用一个RandomAccessFile进行下载

            RandomAccessFile currentPart = new RandomAccessFile(targetFile,

                "rw");

            // 定位该线程的下载位置

            currentPart.seek(startPos);

            // 创建下载线程

            threads[i] = new DownloadThread(startPos, currentPartSize,

                currentPart);

            // 启动下载线程

            threads[i].start();

        }

    }

    // 获取下载的完成百分比

    public double getCompleteRate()

    {

        // 统计多条线程已经下载的总大小

        int sumSize = 0;

        for (int i = 0; i < threadNum; i++)

        {

            sumSize += threads[i].length;

        }

        // 返回已经完成的百分比

        return sumSize * 1.0 / fileSize;

    }

    private class DownloadThread extends Thread

    {

        // 当前线程的下载位置

        private int startPos;

        // 定义当前线程负责下载的文件大小

        private int currentPartSize;

        // 当前线程需要下载的文件块

        private RandomAccessFile currentPart;

        // 定义已经该线程已下载的字节数

        public int length;

        public DownloadThread(int startPos, int currentPartSize,

            RandomAccessFile currentPart)

        {

            this.startPos = startPos;

            this.currentPartSize = currentPartSize;

            this.currentPart = currentPart;

        }

        @Override

        public void run()

        {

            try

            {

                URL url = new URL(path);

                HttpURLConnection conn = (HttpURLConnection) url

                    .openConnection();

                conn.setConnectTimeout(5 * 1000);

                conn.setRequestMethod("GET");

                conn.setRequestProperty(

                    "Accept",

                    "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint,
application/msword, */*");

                conn.setRequestProperty("Accept-Language", "zh-CN");

                conn.setRequestProperty("Charset", "UTF-8");

                InputStream inStream = conn.getInputStream();

                // 跳过startPos个字节,表明该线程只下载自己负责哪部分文件。

                inStream.skip(this.startPos);

                byte[] buffer = new byte[1024];

                int hasRead = 0;

                // 读取网络数据,并写入本地文件

                while (length < currentPartSize

                    && (hasRead = inStream.read(buffer)) != -1)

                {

                    currentPart.write(buffer, 0, hasRead);

                    // 累计该线程下载的总大小

                    length += hasRead;

                }

                currentPart.close();

                inStream.close();

            }

            catch (Exception e)

            {

                e.printStackTrace();

            }

        }

    }

}

MultiThreadDown.java:

package org.xxx.net;

import java.util.Timer;

import java.util.TimerTask;

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.EditText;

import android.widget.ProgressBar;

public class MultiThreadDown extends Activity

{

    EditText url;

    EditText target;

    Button downBn;

    ProgressBar bar;

    DownUtil downUtil;

    private int mDownStatus;

    @Override

    public void onCreate(Bundle savedInstanceState)

    {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        // 获取程序界面中的三个界面控件

        url = (EditText) findViewById(R.id.url);

        target = (EditText) findViewById(R.id.target);

        downBn = (Button) findViewById(R.id.down);

        bar = (ProgressBar) findViewById(R.id.bar);

        // 创建一个Handler对象

        final Handler handler = new Handler()

        {

            @Override

            public void handleMessage(Message msg)

            {

                if (msg.what == 0x123)

                {

                    bar.setProgress(mDownStatus);

                }

            }

        };

        downBn.setOnClickListener(new OnClickListener()

        {

            @Override

            public void onClick(View v)

            {

                // 初始化DownUtil对象

                downUtil = new DownUtil(url.getText().toString(),

                    target.getText().toString(), 4);

                try

                {

                    // 开始下载

                    downUtil.download();

                }

                catch (Exception e)

                {

                    e.printStackTrace();

                }

                // 定义每秒调度获取一次系统的完成进度

                final Timer timer = new Timer();

                timer.schedule(new TimerTask()

                {

                    @Override

                    public void run()

                    {

                        // 获取下载任务的完成比率

                        double completeRate = downUtil.getCompleteRate();

                        mDownStatus = (int) (completeRate * 100);

                        // 发送消息通知界面更新进度条

                        handler.sendEmptyMessage(0x123);

                        // 下载完全后取消任务调度

                        if (mDownStatus >= 100)

                        {

                            timer.cancel();

                        }

                    }

                }, 0, 100);

            }

        });

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: