Android多线程下载(java项目中)

多线程下载在Android开发中经常用到,多下线程下载,其实就是将一个下载任务分布下载,使得下载的速度更快,用户体验更好。
原理很简单:
Android多线程下载(java项目中)_第1张图片

下面我们就来实现以下多线程下载吧;如图
Android多线程下载(java项目中)_第2张图片
根据下载的文件大小开启合理的线程,是一种良好的编码习惯,有时候线程开多了,占用cpu资源浪费,所以,更具需求来来开启线程大小,是一种合理的编码;代码如下:

package mlitdowloadfile;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;

public class Test {
    static HttpURLConnection open;
    static int threadcontext=3;//线程大小
    static String urls="http://localhost:8080/test.zip";
    static int threadfinsh=0;//记录文件是否全部下载完成
    public static void main(String[] args) {

        try {
            URL url=new URL(urls);
            open=(HttpURLConnection) url.openConnection();
            open.setReadTimeout(30000);
            open.setConnectTimeout(30000);
            open.setRequestMethod("GET");
            if (open.getResponseCode()==200) {
                System.out.println("请求成功");
                int length=open.getContentLength();//获得文件大小
                File file=new File(getFileName(urls));
                //创建临时文件,与服务器大小一样
                RandomAccessFile randomAccessFile=new RandomAccessFile(file, "rwd");
                randomAccessFile.setLength(length);
                //计算每个线程下载的大小
                int size=length/threadcontext;
                for (int i = 0; i < threadcontext; i++) {
                    int startindex=i*size;//开始下载位置
                    int endindex=(i+1)*size-1;//结束下载位置
                    if (i==threadcontext-1) {
                        endindex=length-1;
                    }
                    System.out.println("线程"+i+"的开始结束位置"+startindex+"--"+endindex);
                    //开启多线程
                    new downLooad(i, startindex, endindex).start();

                }

            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public static String getFileName(String path){
        int index=path.indexOf(".");

        return path.substring(index+1);

    }
}


class downLooad extends Thread{
    int threadid;
    int startindex;
    int endindex;
    public downLooad(int threadid,int startindex,int endindex){
        this.endindex=endindex;
        this.startindex=startindex;
        this.threadid=threadid;
    }

    @Override
    public void run() {
        try {   
            File temp=new File(threadid+".txt");
            if (temp.exists()) {
                FileInputStream fileInputStream =new FileInputStream(temp);
                InputStreamReader inputStreamReader=new InputStreamReader(fileInputStream);
                BufferedReader bufferedReader=new BufferedReader(inputStreamReader);
                String string=bufferedReader.readLine();
                startindex=Integer.parseInt(string);
                System.out.println("下载位置"+string);
                fileInputStream.close();
            }

        URL url=new URL(Test.urls);
        HttpURLConnection open=(HttpURLConnection) url.openConnection();
        open.setReadTimeout(30000);
        open.setConnectTimeout(30000);
        open.setRequestMethod("GET");
        //设置多线程请求数据范围
        open.setRequestProperty("Range", "bytes="+startindex+"-"+endindex);
        //请求部分数据且成功的状态码

        if (open.getResponseCode()==206) {
            File file=new File(Test.getFileName(Test.urls));
            //创建临时文件,与服务器大小一样
            RandomAccessFile randomAccessFile=new RandomAccessFile(file, "rwd");

            randomAccessFile.seek(startindex);//写入位置进行位移

            InputStream inputStream=open.getInputStream();
            int len=0;
            int lening=0;

            byte[] buffer=new byte[4096];

            while ((len=inputStream.read(buffer))!=-1) {
                randomAccessFile.write(buffer, 0, len);
            lening+=len;
            //添加断点续传
            RandomAccessFile rAccessFile=new RandomAccessFile(temp, "rwd");
            rAccessFile.write((startindex+lening+"").getBytes("utf-8"));
            rAccessFile.close();
            System.out.println("线程"+threadid+"已经下载"+lening);
            }

            randomAccessFile.close();
            System.out.println("线程"+threadid+"下载完毕");
            Test.threadfinsh++;
            //线程安全(同步语句块)
            synchronized (url) {
                if (Test.threadfinsh==Test.threadcontext) {
                    for (int i = 0; i <Test.threadfinsh; i++) {
                        File tempFile=new File(i+".txt");
                        tempFile.delete();
                    }
                    Test.threadfinsh=0;
                }
            }
        }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

你可能感兴趣的:(多线程,android)