mercredi 6 mai 2015

Android studio multithreaded downloader

I am trying to make a multuthreaded downloader which can download a given file by breaking it into 3 chunks and downloading in parallel. The issue is, when I run the code, it seems that Thread 2 doesnt start unless Thread 1 finishes and Thread 1 doesnt start until Thread 0 finishes. I want all the threads to run simultaneously, following is my code:

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;
}

The above code is being called like this:

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://ift.tt/1FPNdqb").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://ift.tt/1FPNdqb", startByte[i], endByte[i]).execute();
            }
        }
    }catch(IOException e){
        Log.e("DownloaderClass", "Exception getting file size: " + e.getMessage());
    }
    return null;
}

As you will see, I have two different classes, both extending AsynTask, and the flow is like this: Activity calls the first class on a click button and the first class class the second class in a loop of 3 iterations.

Sample URL: http://ift.tt/1FPNdqb

Aucun commentaire:

Enregistrer un commentaire