Since this section is about learning how to use multi-threaded downloads, let's first understand what a multi-threaded download is, and before you know what a multithreaded download is, you need to be aware of what a single-threaded download should be.
is the original single-threaded download, so the single-threaded download is slow, because only one task is working.
In this case, 3 threads download a file, which is faster than the 1-thread-per-file. So it's faster to download data in multiple threads.
Now that we know the principle of multi-threaded downloading, we analyze how multiple threads download data and how to save it.
Knowing how multi-threaded downloads work and how each thread holds the data, start writing code.
1: Of course, the size of the data must be obtained before you know how much download is allocated to each thread
I downloaded an EXE file on the server named: Wireshark.exe
Get the size of the file from the server first, and calculate the size interval that each thread should download
public void Downloade (View v) { thread thread = new Thread () { //server address String path = "/HTTP/ 192.168.1.123:8080/wireshark.exe "; @Override public Void Run () { try {URL url = new URL (path); HttpURLConnection conn = (httpurlconnection) url.openconnection (); Conn.setrequestmethod ("GET"); conn.setreadtimeout (conn.setreadtimeout); if (conn.getresponsecode () = = 200) {//Gets the total size of the data int length = Conn.getcontentlength (); per thread size int size = length/threadcount;for (int i = 0; i < ThreadCount; i++) {int startIndex = i * size;int EndIndex = ( i + 1) *size-1;//the end address of the last thread is the total file size -1if (i = = threadCount-1) {endIndex = length-1;} System.out.println (the download interval for "thread" + i + "is:" + StartIndex + "---" + endIndex);}} catch (Exception e) {//TODO auto-generated catch Blocke.printstacktrace ();} } ; Thread.Start (); }
Printing results are:
You can see that the size is correct. The total size is 29849552 size
2: Now that we've divided the download interval for each thread, we'll start downloading
At the beginning of the download, it is necessary to allocate a temporary file of the same size as the download file on the storage device, so as to avoid insufficient storage during the download.
SYSTEM.OUT.PRINTLN ("thread" + i + "Download interval is:" + StartIndex + "---" + endIndex);//open threadcount to download data new Downloadthread (Startinde X, EndIndex, I). Start ();
Class Downloadthread extends thread{int startindex;//start position int endindex;//end position int threadid;//thread ID//construction method P Ublic downloadthread (int startIndex, int endIndex, int threadId) {super (); this.startindex = Startindex;this.endindex = en Dindex;this.threadid = threadId;} @Overridepublic void Run () {///This time needs to request the data to be downloaded URL url;try {url = new URL (path); HttpURLConnection conn = (httpurlconnection) url.openconnection (); Conn.setrequestmethod ("GET"); conn.setreadtimeout Conn.setreadtimeout (5000);//Set the interval conn.setrequestproperty for this HTTP request data ("range", "bytes=" + StartIndex + "-" + ENDINDEX);//Request part of the data, the return code is 206if (conn.getresponsecode () = = 206) {//The data taken at this time only the size of the given interval above inputstream is = Conn.getinputstream (); byte[] B = new Byte[1024];int len = 0;int total = 0;//Opens the temp file again. file File = new file (Environment.getex Ternalstoragedirectory (), filename); Randomaccessfile RAF = new Randomaccessfile (file, "RWD");//Specify the write location of the file to Startindexraf.seek (StartIndex); while (len = Is.read (b))! =-1) {raf.write (b, 0, Len); Total + =Len SYSTEM.OUT.PRINTLN ("thread" + threadId + "downloaded" + total); SYSTEM.OUT.PRINTLN ("thread" + threadId + "---------------download completed-------------------"); Raf.close ();}} catch (Exception e) {//TODO auto-generated catch Blocke.printstacktrace ();}} }
You can see from the print that the download was successful.
3: Since the download, the user knows the progress of the download. We use the progress bar to show the current progress
Set Maximum Progress
Gets the total size of the data int length = Conn.getcontentlength ();//sets the maximum Pbar.setmax (length) of the progress bar;//size of each thread int size = Length/threadcount ;
This is the current progress
Raf.write (b, 0, Len); total + = Len; SYSTEM.OUT.PRINTLN ("thread" + threadId + "downloaded" + total);//Set current progress, is the sum of 3 threads currprogress + = len;pbar.setprogress (currprogress );
Then set the text display to the current scale. To use a message to update the UI
Handler Handler = new Handler () {public void Handlemessage (Android.os.Message msg) {//Display the download scale to a long type, int is sometimes not big enough tview.settext ((long) pbar.getprogress () * 100/pbar.getmax () + "%");};
:
Next, implement the breakpoint to resume:
File Bakfile = new file (Environment.getexternalstoragedirectory (), ThreadId + ". txt"), try {//To determine if the files exist if (bakfile.exists ()) {FileInputStream FIS = new FileInputStream (bakfile); BufferedReader breader = new BufferedReader (FIS);//read out the total progress of the last download from the progress temp file and add it to the original start location. Get a new start position int lastprogress = Integer.parseint (Breader.readline ()); StartIndex + = lastprogress;// Show the progress of the last download to the progress bar currprogress + = lastprogress;pbar.setprogress (currprogress);//Send a message, Let the main thread refresh the text progress handler.sendemptymessage (1); Fis.close ();}
In the download time, you need to create a configuration file, to prevent some reasons during the download process to stop the download, when the subsequent download, or the last download of the place to download
while (len = Is.read (b))! =-1) {raf.write (b, 0, Len); total + = Len; SYSTEM.OUT.PRINTLN ("thread" + threadId + "downloaded" + total);//Set current progress, is the sum of 3 threads currprogress + = len;pbar.setprogress (currprogress );//update the text by sending a message. The progress bar does not need to refresh the UI by sending a message, because the progress bar itself is a handler.sendemptymessage (1) used in another task;//Saves the current download progress to the configuration file Randomaccessfile bakrafile = new Randomaccessfile (Bakfile, "RWD"), Bakrafile.write ((Total + ""). GetBytes ()); Bakrafile.close ();
Can normally support breakpoints continuous download
The downloaded file can run normally, I will download the file to Feiq, because Wireshark is a bit big
http://download.csdn.net/detail/longwang155069/8991785
Source
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Android Network learning using multi-threaded download, support for the continuation of the breakpoint