单线程下载和多线程下载

单线程下载

1.单线程下载比较简单,就是开启一个线程,然后打开URL连接按照字节的方式读取流,写入文件就可了
2.用AsyncTask实现单线程下载

class DownLoadSingle extends AsyncTask<String,Integer,String>{
        @Override
        protected void onProgressUpdate(Integer... values) {
            mProgressBar.setProgress((int) (values[0]*100.0/values[1]));//设置下载进度
            super.onProgressUpdate(values);
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
        }

        @Override
        protected String doInBackground(String... params) {
            try {

//                URL url=new URL("http://dl.bizhi.sogou.com/images/2015/03/12/1113537.jpg");//网络图片
                URL url=new URL("http://192.168.0.103:8080/ThirteenAugMyServer/music/SeeYouAgain.mp3");//本地服务器图片
                URLConnection connection=url.openConnection();//打开url
                int length=connection.getContentLength();//得到内容长度
                InputStream is=connection.getInputStream();//得到输入流
                File file=new File(Environment.getExternalStorageDirectory(),"See You Again.mp3");
                if (!file.exists()){
                    file.createNewFile();
                }
                FileOutputStream os=new FileOutputStream(file);//输出流
                byte[] array=new byte[1024];
                int sum=0;
                int index=is.read(array);
                while (index!=-1){
                    os.write(array,0,index);
                    sum+=index;
                    publishProgress(sum,length);
                    index=is.read(array);
                }
                os.flush();
                os.close();
                is.close();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

3.然后启动这个线程

 DownLoadSingle task=new DownLoadSingle();
                task.execute();

多线程下载

1.首先创建一个类继承与Thread,在该类中,构建一个有参构造器,其中包括文件开始位置,文件结束位置,url路径,file路径,然后重写run方法

2.重写run方法中,首先打开url路径,设置文件下载起始和结束位置,然后对文件进行读写操作

public class MultiThread extends Thread {
    private long start;
    private long end;
    private String urlPath;
    private String filePath;
    private int sum=0;

    public int getSum() {
        return sum;
    }

    /***
     *  多线程构造器,用于传入下载内容的起始,末尾,url路径,file路径
     * @param start  下载内容的起始位置
     * @param end     下载内容的末位置
     * @param urlPath  url路径
     * @param filePath  file路径
     */
    public MultiThread(long start, long end, String urlPath, String filePath) {
        this.start = start;
        this.end = end;
        this.urlPath = urlPath;
        this.filePath = filePath;
    }
    //重写了run方法
    @Override
    public void run() {
        try {
            URL url=new URL(urlPath);
            URLConnection connection=url.openConnection();//打开url路径
            connection.setAllowUserInteraction(true);//
            connection.setRequestProperty("Range", "bytes=" + start + "-"
                    + end);//返回此连接指定的一般请求属性值
            InputStream is=connection.getInputStream();
            byte[] array=new byte[1024];
            int index=is.read(array);
            File file=new File(filePath);
            RandomAccessFile randomAccessFile=new RandomAccessFile(file,"rw");//随机文件的读取和写入,“rw”表示写入文件
            randomAccessFile.seek(start);//设置到文件开头测量到的文件指针偏移量
            while (index!=-1){
                randomAccessFile.write(array,0,index);
                sum+=index;            //将在在的总字节数返回到sum中
                index=is.read(array);
            }
            //关闭流
            randomAccessFile.close();
            is.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3.创建一个新的线程,打开url路径,得到文件的总大小,然后创建一个文件,将url所指的文件写入到该文件中,然后创建5个线程,对这五个线程分别分配不同的起始位置,在将创建的线程放入到线程数组中去,方便管理,同时得到下载进度的信息

new Thread(new Runnable() {
                    @Override
                    public void run() {
//                        String urlPath="http://dl.bizhi.sogou.com/images/2015/03/12/1113537.jpg";
                        String urlPath="http://192.168.0.100:8080/ThirteenAugMyServer/music/SeeYouAgain.mp3";
                        URL url= null;
                        try {
                            url = new URL(urlPath);
                            URLConnection connection=url.openConnection();
                            length=connection.getContentLength();
                            File file=new File(Environment.getExternalStorageDirectory(),"SeeYouAgain.mp3");
                            if (!file.exists()){
                                file.createNewFile();
                            }
                            //开启5个线程,将5个线程放入到线程数组中,然后用于得到文件下载进度信息
                            MultiThread[] threads=new MultiThread[5];
                            for (int i=0;i<5;i++){
                                MultiThread thread=null;
                                if(i==4){
                                    thread = new MultiThread(length / 5*4, length , urlPath, file.getAbsolutePath());
                                }else {
                                    thread = new MultiThread(length / 5 * i, length / 5 * (i + 1)-1, urlPath, file.getAbsolutePath());
                                }
                                thread.start();
                                threads[i]=thread;
                            }
                            //得到下载资源的数量,用来设置进度条
                            boolean isFinish=true;
                            while (isFinish){
                                int sum=0;
                                for(MultiThread thread:threads){
                                    sum+=thread.getSum();
                                }
                                handler.obtainMessage();
                                Message msg=new Message();
                                msg.what=DOWN_SUM;
                                msg.arg1=sum;
                                handler.sendMessage(msg);
                                if (sum+10>=length){
                                    isFinish=false;
                                }
                                //为何要加休眠,不加休眠会报错
                                //是为了给progressBar反应的时间
                                Thread.sleep(1000);
                            }

                        } catch (MalformedURLException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }


                    }
                }).start();

4.设置进度条

private Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case DOWN_SUM:
                    mProgressBar.setProgress((int) (msg.arg1*100.0/length));
                    break;
                default:
                    break;
            }
        }
    };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值