Android™
Android™
HTTP Download in Parallel with Simultaneous Range Requests
See more HTTP Examples
Demonstrates how to download a large file with parallel simultaneous requests, where each request downloads a segment (range) of the remote file.Chilkat Android™ Downloads
// Important: Don't forget to include the call to System.loadLibrary
// as shown at the bottom of this code sample.
package com.test;
import android.app.Activity;
import com.chilkatsoft.*;
import android.widget.TextView;
import android.os.Bundle;
public class SimpleActivity extends Activity {
private static final String TAG = "Chilkat";
// Called when the activity is first created.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean success = false;
// This requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
CkHttp http = new CkHttp();
// First get the size of the file to be downloaded.
String url = "https://www.chilkatsoft.com/hamlet.xml";
CkHttpResponse resp = new CkHttpResponse();
success = http.HttpNoBody("HEAD",url,resp);
if (success == false) {
Log.i(TAG, http.lastErrorText());
return;
}
int remoteFileSize = resp.get_ContentLength();
Log.i(TAG, "Downloading " + String.valueOf(remoteFileSize) + " bytes...");
// Let's download in 4 chunks.
// (the last chunk will be whatever remains after the 1st 3 equal sized chunks)
int chunkSize = remoteFileSize / 4;
// The Range header is used to download a range from a resource
// Range: bytes=<range-start>-<range-end>
// or
// Range: bytes=<range-start>-
// We're writing code this way for clarity..
CkHttp http1 = new CkHttp();
CkHttp http2 = new CkHttp();
CkHttp http3 = new CkHttp();
CkHttp http4 = new CkHttp();
CkStringBuilder sbRange = new CkStringBuilder();
sbRange.SetString("bytes=<range-start>-<range-end>");
int numReplaced = sbRange.ReplaceI("<range-start>",0);
numReplaced = sbRange.ReplaceI("<range-end>",chunkSize - 1);
Log.i(TAG, sbRange.getAsString());
http1.SetRequestHeader("Range",sbRange.getAsString());
sbRange.SetString("bytes=<range-start>-<range-end>");
numReplaced = sbRange.ReplaceI("<range-start>",chunkSize);
numReplaced = sbRange.ReplaceI("<range-end>",2 * chunkSize - 1);
Log.i(TAG, sbRange.getAsString());
http2.SetRequestHeader("Range",sbRange.getAsString());
sbRange.SetString("bytes=<range-start>-<range-end>");
numReplaced = sbRange.ReplaceI("<range-start>",2 * chunkSize);
numReplaced = sbRange.ReplaceI("<range-end>",3 * chunkSize - 1);
Log.i(TAG, sbRange.getAsString());
http3.SetRequestHeader("Range",sbRange.getAsString());
sbRange.SetString("bytes=<range-start>-");
numReplaced = sbRange.ReplaceI("<range-start>",3 * chunkSize);
Log.i(TAG, sbRange.getAsString());
http4.SetRequestHeader("Range",sbRange.getAsString());
// Start each range download
CkTask task1 = http1.DownloadAsync(url,"qa_output/chunk1.dat");
task1.Run();
CkTask task2 = http2.DownloadAsync(url,"qa_output/chunk2.dat");
task2.Run();
CkTask task3 = http3.DownloadAsync(url,"qa_output/chunk3.dat");
task3.Run();
CkTask task4 = http4.DownloadAsync(url,"qa_output/chunk4.dat");
task4.Run();
// Wait for the downloads to complete.
int numLive = 4;
while (numLive > 0) {
numLive = 0;
if (task1.get_Live() == true) {
numLive = numLive + 1;
}
if (task2.get_Live() == true) {
numLive = numLive + 1;
}
if (task3.get_Live() == true) {
numLive = numLive + 1;
}
if (task4.get_Live() == true) {
numLive = numLive + 1;
}
if (numLive > 0) {
// SleepMs is a convenience method to cause the caller to sleep for N millisec.
// It does not cause the given task to sleep..
task1.SleepMs(10);
}
}
// All should be downloaded now..
// Examine the result of each Download.
int numErrors = 0;
if (task1.GetResultBool() == false) {
Log.i(TAG, task1.resultErrorText());
numErrors = numErrors + 1;
}
if (task2.GetResultBool() == false) {
Log.i(TAG, task2.resultErrorText());
numErrors = numErrors + 1;
}
if (task3.GetResultBool() == false) {
Log.i(TAG, task3.resultErrorText());
numErrors = numErrors + 1;
}
if (task4.GetResultBool() == false) {
Log.i(TAG, task4.resultErrorText());
numErrors = numErrors + 1;
}
if (numErrors > 0) {
return;
}
// All downloads were successful.
// Compose the file from the parts.
CkFileAccess fac = new CkFileAccess();
success = fac.ReassembleFile("qa_output","chunk","dat","qa_output/hamlet.xml");
if (success == false) {
Log.i(TAG, fac.lastErrorText());
}
else {
Log.i(TAG, "Success.");
}
// Let's download in the regular way, and then compare files..
success = http.Download(url,"qa_output/hamletRegular.xml");
// Compare files.
boolean bSame = fac.FileContentsEqual("qa_output/hamlet.xml","qa_output/hamletRegular.xml");
Log.i(TAG, "bSame = " + String.valueOf(bSame));
}
static {
System.loadLibrary("chilkat");
// Note: If the incorrect library name is passed to System.loadLibrary,
// then you will see the following error message at application startup:
//"The application <your-application-name> has stopped unexpectedly. Please try again."
}
}