Java Android studio多线程下载程序

Java Android studio多线程下载程序,java,android,multithreading,android-asynctask,Java,Android,Multithreading,Android Asynctask,我正在尝试制作一个多线程下载程序,它可以通过将给定文件分成3个块并并行下载来下载问题是,当我运行代码时,线程2似乎在线程1完成之前不会启动,而线程1在线程0完成之前不会启动。我希望所有线程同时运行,下面是我的代码: protected Void doInBackground(Void... params){ try{ if(ThreadName == "1") { Log.d("DownloaderSleeper", "puttin

我正在尝试制作一个多线程下载程序,它可以通过将给定文件分成3个块并并行下载来下载问题是,当我运行代码时,线程2似乎在线程1完成之前不会启动,而线程1在线程0完成之前不会启动。我希望所有线程同时运行,下面是我的代码

protected Void doInBackground(Void... params){
    try{
        if(ThreadName == "1")
        {
            Log.d("DownloaderSleeper", "putting thread 1 to sleep");
            Thread.sleep(3000);
        }
        URL url = new URL(UrlString);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestProperty("Range", "bytes=" + StartingByte.toString() + "-" + EndingByte.toString());
        connection.connect();
        //File f = new File(TargetFileName);
        Log.d("DownloaderThreadClass", F.toString() + TargetFileName);
        RandomAccessFile file = new RandomAccessFile(F, "rw");
        file.seek(StartingByte);
        InputStream stream = connection.getInputStream();
        int bufferSize = 1024;
        byte[] buffer = new byte[bufferSize];
        int nRead = 0;
        int start = 0;
        int i = 0;
        while ((nRead = stream.read(buffer, start, bufferSize)) > 0) {
            file.write(buffer, 0, nRead);
            //start += bufferSize + 1;
            Log.i("DownloaderThreadClass:" + ThreadName + ": ", "Chunk: " + i + "copied" );
            i += 1;
        }
        file.close();
        stream.close();
        connection.disconnect();
    }catch(Exception e){
        Log.e("DownloaderThreadClass", "Some exception: " + e.getMessage());
    }

    return null;
}
上述代码的调用方式如下:

protected Void doInBackground(Void... params) {
    int chunkSize = 0;
    int[] startByte = new int[3];
    int[] endByte = new int[3];
    try{
        int fileSize = this.getFileSize();
        if(fileSize > 0 && fileSize <= 1024 * 1024){
            new DownloaderThreadClass("1", f, "http://sample-videos.com/video/mp4/720/big_buck_bunny_720p_2mb.mp4").execute();
        }else if(fileSize > 1024 * 1024){
            chunkSize = Math.round(fileSize / 3);
            startByte[0] = 0;
            endByte[0] = chunkSize - 1;
            startByte[1] = chunkSize;
            endByte[1] = chunkSize + chunkSize - 1;
            startByte[2] = chunkSize + chunkSize;
            endByte[2] = fileSize;
            for (int i = 0; i < 3; i++){
                new DownloaderThreadClass(Integer.toString(i), f, "http://sample-videos.com/video/mp4/720/big_buck_bunny_720p_2mb.mp4", startByte[i], endByte[i]).execute();
            }
        }
    }catch(IOException e){
        Log.e("DownloaderClass", "Exception getting file size: " + e.getMessage());
    }
    return null;
}
受保护的Void doInBackground(Void…params){
int chunkSize=0;
int[]起始字节=新int[3];
int[]endByte=新的int[3];
试一试{
int fileSize=this.getFileSize();
if(文件大小>0&&fileSize 1024*1024){
chunkSize=Math.round(fileSize/3);
起始字节[0]=0;
endByte[0]=chunkSize-1;
startByte[1]=块大小;
endByte[1]=chunkSize+chunkSize-1;
startByte[2]=chunkSize+chunkSize;
endByte[2]=文件大小;
对于(int i=0;i<3;i++){
新的DownloaderThreadClass(Integer.toString(i),f,“http://sample-videos.com/video/mp4/720/big_buck_bunny_720p_2mb.mp4,开始字节[i],结束字节[i])。执行();
}
}
}捕获(IOE异常){
Log.e(“DownloaderClass”,“获取文件大小异常:”+e.getMessage());
}
返回null;
}
正如您将看到的,我有两个不同的类,都扩展了AsynTask,流程是这样的:Activity在单击按钮时调用第一个类,而第一个类在3次迭代的循环中调用第二个类


示例URL:

对于实际并行性,应执行:

public final AsyncTask<Params, Progress, Result> executeOnExecutor (Executor exec, Params... params)
public final AsyncTask executeOnExecutor(Executor exec,Params…Params)
而不是

public final AsyncTask<Params, Progress, Result> execute (Params... params)
公共最终异步任务执行(Params…Params)
签出以下评论:

首次引入时,AsyncTasks是在单个服务器上串行执行的 背景线程。从甜甜圈开始,它被改成了一个 允许多个任务并行运行的线程。从 蜂窝,任务在单个线程上执行,以避免常见的 并行执行导致的应用程序错误

如果确实需要并行执行,可以调用 executeOnExecutor(java.util.concurrent.Executor,对象[])与 线程池执行器