多线程下载 待优化

这个okhttp的话直接用原生的就可以了

public class MainActivity extends AppCompatActivity {
    //要下载的文件地址
    private String url="https://qd.myapp.com/myapp/qqteam/AndroidQQ/mobileqq_android.apk";
    //设置线程数量   线程运行时的长度
    private int counter=3,runningThreadCount=0,blockSize;
    private ProgressBar bar1,bar2,bar3;
    Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 0:
                    bar1.setProgress(msg.arg1);

                    break;
                case 1:
                    bar2.setProgress(msg.arg1);
                    break;
                case 2:
                    bar3.setProgress(msg.arg1);
                    break;
            }
        }
    };

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bar1=findViewById(R.id.bar1);
        bar2=findViewById(R.id.bar2);
        bar3=findViewById(R.id.bar3);

    }

    public void cc(View view) {
        
        OKhttptils.Post(url, new HashMap<String, String>(), new HttpCallBack() {

            @Override
            public void success(String response, long Length) {
                Log.d("aaaaaa", "success: "+Length);
                Log.d("aaaaaa", "success: "+response);
                try {
                    Log.d("aaaaaa", ": "+getExternalCacheDir().toString());
                    //创建一个空的文件夹并且设置文件长度大小等于地址上的文件大小
                    RandomAccessFile randomAccessFile = new RandomAccessFile(getExternalCacheDir() + getDownloadFileName(url),"rw");
                    //给空文件设置大小
                    randomAccessFile.setLength(Length);
                    //关闭文件读取流
                    randomAccessFile.close();
                    //每一个线程分配的下载长度
                    blockSize= (int) Length / counter;
                    bar1.setMax(blockSize);
                    bar2.setMax(blockSize);
                    bar3.setMax(blockSize);
                    //分配每一个线程的下载位置
                    for (int i = 0; i <counter ; i++) {
                        int startPosition = i * blockSize;
                        int endPosition = (i+1) * blockSize - 1;
                        //如果等于最后一个的话就直接设置结束位置
                        if(i==(counter-1)){
                            endPosition = (int) Length-1;
                        }
                        Log.d("aaaaaa", ": Thread"+i+"startPosition"+startPosition+"-----endPosition"+endPosition);
                        //创建线程
                        new DownloadThread(i,startPosition,endPosition).start();
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }

            }

            @Override
            public void fail(String response) {

            }
        });
    }
    /*
    * 从网络路径获取文件名
    * 网络路径   path
    * 文件名    return
    *
    * */
    private String getDownloadFileName(String path) {
        return path.substring(path.lastIndexOf("/")+1);
    }

    /*
    * 下载文件的线程
    * */
    private class DownloadThread extends Thread{
        //线程第几个   起始位置    结束位置
        private int i,startPosition,endPosition;
        public DownloadThread(int i, int startPosition, int endPosition) {
            this.i=i;
            this.startPosition=startPosition;
            this.endPosition=endPosition;
        }

        @Override
        public void run() {
            super.run();

                try {
                    Log.d("aaaaaa", ": 4");
                    //创建每个线程对应的文件记录暂停下载的位置
                    File file = new File(getExternalCacheDir().toString(),counter + getDownloadFileName(url) + i + ".txt");
                    //如果这个记录文件存在的话直接读取
                    if(file.exists()&&file.length()>0){
                        FileInputStream fileInputStream = new FileInputStream(file);
                        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
                        //读取上一次暂停时结尾的位置
                        String lastPosition = bufferedReader.readLine();
                        //直接把值赋值给这个线程的起始位置
                        startPosition = Integer.parseInt(lastPosition);
                        fileInputStream.close();
                    }else {
                        Log.d("aaaaaa", ": Thread"+i+"startPosition"+startPosition+"-----endPosition"+endPosition);
                        Request request = new Request.Builder()
                                //确定下载的范围,添加此头,则服务器就可以跳过已经下载好的部分
                                .addHeader("RANGE", "bytes=" + startPosition + "-" + endPosition)
                                .url(url)
                                .build();
                        Call call = new OkHttpClient.Builder().build().newCall(request);
                        call.enqueue(new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                                Log.d("aaaaaa", ": "+e.toString());
                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                                //得到下载文件输入流
                                InputStream inputStream = response.body().byteStream();
                                //如果有这个文件就打开  没有则创建
                                RandomAccessFile rw = new RandomAccessFile(getExternalCacheDir() + getDownloadFileName(url), "rw");
                                //
                                rw.seek(startPosition);
                                //缓存区  读取文件并且写入文件
                                byte[] buffer = new byte[1024];
                                int len = -1;
                                //统计下载长度位置
                                int total = 0;

                                while ((len = inputStream.read(buffer)) != -1){
                                    rw.write(buffer,0,len);
                                    total += len;
                                    RandomAccessFile randomAccessFile = new RandomAccessFile(getExternalCacheDir().toString()+counter + getDownloadFileName(url) + i + ".txt","rwd");
                                    //保存已经下载的位置长度
                                    randomAccessFile.write(String.valueOf(startPosition + total).getBytes());
                                    randomAccessFile.close();
                                    Message message = new Message();
                                    message.what=i;
                                    message.arg1=total;
                                    handler.sendMessage(message);
                                }
                                inputStream.close();
                                rw.close();
                                Log.d("aaaaaa", ": Thread"+i+"下载完成");
                            }
                        });
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    synchronized (MainActivity.this){
                        runningThreadCount--;
                        if(runningThreadCount<=0){
                            Log.d("aaaaaa", ": "+"下载完成");
                            for (int j = 0; j < counter; j++) {

                                File file = new File(getExternalCacheDir().toString()+ counter + getDownloadFileName(url) + i + ".txt");
                                Log.d("aaaaaa", ": "+file.delete());
                            }
                        }
                    }
                }
            }
    }


}


2.布局

<LinearLayout
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

   <EditText
       android:id="@+id/ed1"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:hint="线程数量"
       tools:ignore="HardcodedText,TextFields" />
    <EditText
        android:id="@+id/ed2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="下载文件的路径"
        tools:ignore="HardcodedText,TextFields" />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="下载"
        tools:ignore="HardcodedText"
        android:onClick="cc"/>
    <LinearLayout
        android:id="@+id/layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:ignore="UselessLeaf">
        <ProgressBar
            android:id="@+id/bar1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="@android:style/Widget.DeviceDefault.ProgressBar.Horizontal"/>
        <ProgressBar
            android:id="@+id/bar2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="@android:style/Widget.DeviceDefault.ProgressBar.Horizontal"/>
        <ProgressBar
            android:id="@+id/bar3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="@android:style/Widget.DeviceDefault.ProgressBar.Horizontal"/>

    </LinearLayout>

</LinearLayout>


猜你喜欢

转载自blog.csdn.net/qq_15059163/article/details/80794348