Android Multi-threaded file downloader

Source: Internet
Author: User


This application is to implement the input file of the network address, click the button to start the download, the download process has a progress bar and the following text prompt progress,

During the download, the button is not clickable, prevents the repeated download, and the toast prompt is displayed after the download.

and the Reply button clickable, the progress bar will also be emptied, of course, if the download end of the application process will be saved progress,

The next time you download the same file, it will be downloaded from the progress record, saving traffic and time.

App permissions required by the application:

Access Network permissions

<uses-permission android:name= "Android.permission.INTERNET"/>

Write permissions for external storage

<uses-permission android:name= "Android.permission.WRITE_EXTERNAL_STORAGE"/>

Layout file Code

<linearlayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http// Schemas.android.com/tools "android:layout_width=" match_parent "android:layout_height=" Match_parent "Android:orien tation= "Vertical" tools:context= ". Mainactivity "> <edittext android:id=" @+id/et_path "android:layout_width=" Match_parent "Android         oid:layout_height= "Wrap_content" android:ems= "android:hint=" Please enter the address of the download file "android:singleline=" true " android:text= "Http://172.22.64.193:8080/test.exe" > </EditText> <tablelayout Android:layo Ut_width= "Match_parent" android:layout_height= "wrap_content" > <tablerow android:layout_wid Th= "Match_parent" android:layout_height= "wrap_content" > <progressbar android:i D= "@+id/pb" style= "Android:attr/progressbarstylehorizontal" android:layout_width= "Match_par      Ent          android:layout_height= "Wrap_content" android:layout_weight= "8"/> <textview Android:id= "@+id/tv_progressnumber" android:layout_width= "Match_parent" android:l                ayout_height= "Wrap_content" android:layout_weight= "2" android:gravity= "center" android:text= "0%"/> </TableRow> </TableLayout> <button android:id= "@+id/bt_startd Ownlode "android:layout_width=" match_parent "android:layout_height=" wrap_content "android:onclick=" St Artdownlode "android:text=" to start the download "/></linearlayout>

Core Code

Package Com.examp.mutildownloader;import Java.io.file;import Java.io.fileinputstream;import java.io.InputStream; Import Java.io.randomaccessfile;import java.net.httpurlconnection;import java.net.url;import android.app.Activity; Import Android.os.bundle;import android.os.environment;import Android.os.handler;import Android.os.Message;import Android.text.textutils;import Android.view.view;import Android.widget.button;import Android.widget.EditText; Import Android.widget.progressbar;import android.widget.textview;import android.widget.toast;/** * multi-threaded download under Android, Breakpoint Download * * @author Martindong * */public class Mainactivity extends Activity {//SD card path private static final File SD = Envi Ronment.getexternalstoragedirectory ();p rivate static final int downlode_error = 1;private static final int Downlode_ SUCCESS = 2;private static final int downlode_delete_temp = 3;public static final int progress_number_change = 4;//defines the number of threads private static int threadcount = 3;//defines the number of threads in the current inventory private static int RunningthrEAD = 3;//component Get private EditText et_path;private ProgressBar pb;private Button bt_startdownlode;private TextView tv_progr essnumber;//definition stored file name private String filename;//Set progress bar progress//progress bar data public int progresstemp = 0;//Define message handling private Handler Han Dler = new Handler () {@Overridepublic void Handlemessage (Message msg) {switch (msg.what) {case DOWNLODE_ERROR:Toast.makeT Ext (Getapplicationcontext (), "Download failed ....", Toast.length_short). Show (); Break;case downlode_success://Settings button available Bt_ Startdownlode.setenabled (TRUE);//emptying Progress progresstemp = 0;pb.setprogress (progresstemp);//Text Clear 0tv_ Progressnumber.settext ("0%"); Toast.maketext (Getapplicationcontext (), "Download succeeded ...", Toast.length_short). Show (); Break;case downlode_delete_temp: Toast.maketext (Getapplicationcontext (), "Delete progress file ....", Toast.length_short). Show (); Break;case Progress_number_ CHANGE:tv_progressNumber.setText (pb.getprogress () * 100/pb.getmax () + "%"); break;}}; @Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); SetcontEntview (r.layout.activity_main); Et_path = (EditText) Findviewbyid (R.id.et_path);//Get component PB = (ProgressBar) Findviewbyid (R.ID.PB); Bt_startdownlode = (Button) Findviewbyid (r.id.bt_startdownlode); tv_progressnumber = (TextView ) Findviewbyid (r.id.tv_progressnumber);} public void Startdownlode (view view) {//Settings button is not clickable//prevents duplicate commit bt_startdownlode.setenabled (FALSE);//Gets the downloaded path final from the control String path = Et_path.gettext (). toString (). Trim ();//Gets the location of the last "/" of the input address that appears int lastIndex = Path.lastindexof ("/");// Get file name and format filename = path.substring (lastIndex + 1, path.length ()); SYSTEM.OUT.PRINTLN ("filename is called ===============" + filename);//Determine if the path is valid if (Textutils.isempty (path)) {Toast.maketext (this, "Please enter a valid download path ...", Toast.length_short). Show (); return;} To avoid conflicts with the main thread, turn on the sub-thread completion, avoid the ANR problem new thread () {public void run () {try {///1, connect to the server, get a file, get the file size as the server's file Temp file//String Path = "Http://172.22.64.193:8080/tomcat.css"; URL url = new URL (path); HttpURLConnection conn = (httpurlconnection) url.openconnection ();//Set timeout Conn.setconnecttimEout (5000);//Set Request mode Conn.setrequestmethod ("get");//Get the return code of the server int code = CONN.GETRESPONSECODE ();//Determine the return code if (code = = 200) {//Gets the length of the returned int length = Conn.getcontentlength ();//sets the maximum value of the progress bar Pb.setmax (length); SYSTEM.OUT.PRINTLN ("Total file length:" + length);//Create a temporary file that is consistent with the server size on the client randomaccessfile RAF = new Randomaccessfile (SD + "/" + FileName, "RWD");//Specify the size of the temporary file raf.setlength (length);//Release Resource raf.close ();//average file size of each thread int blockSize = length/ threadcount;//Set Active Thread runningthread = threadcount;for (int threadId = 1; threadId <= threadcount; threadid++) {//thread start Download location int startIndex = (threadId-1) * blocksize;//thread end position int endIndex = threadId * blocksize-1;//Determine if it is the last thread if (thread Id = = ThreadCount) {//setting ends at the end of the file Endindex = length;} System.out.println ("Thread:" + threadid+ "Download: Start position >>>>>>>>" + startindex+ "End >>>>> >>>>> "+ endIndex); new Downlodethread (Path, ThreadId, Startindex,endindex). Start ();}}} catch (Exception e) {//TODO auto-generated catch Blocke.Printstacktrace ();}};}. Start ();} /** * Download the file's child thread class, each thread downloads the corresponding location file data * * @author Martindong * */public class Downlodethread extends Thread {private String PA th;private int threadid;private int startindex;private int endindex;/** * * @param path * File Download paths * @param thr EADID * Thread ID * @param startIndex * thread start position * @param endIndex * thread End location */public Downlodet  Hread (String path, int threadId, int startindex,int endIndex) {This.path = Path;this.threadid = Threadid;this.startindex = Startindex;this.endindex = EndIndex;} @Overridepublic void Run () {try {//check if there is a file for download history tempfile = new File (SD + "/" + threadId + ". txt");//=============== ========== Breakpoint Record Operation ===============================if (Tempfile.exists () && tempfile.length () > 0) {// File input stream FileInputStream fis = new FileInputStream (tempfile);//intermediate variable, cache function byte[] Tempbuffer = new byte[1024];// Gets the data size of the progress file int length = Fis.read (Tempbuffer);//Gets the data of the progress file string historydata = new String (tempbuffer, 0, length);//Replace the progress data with int historydataint = Integer.parseint (historydata);//If it is a breakpoint transfer, initialize the progress bar progress//Get the progress of each thread already downloaded int temp = historydataint-startindex;//for Progress re-assignment progresstemp + = temp;//Modify the true download location StartIndex = Historydataint;fis.close ();} ========================= Breakpoint Record operation ===============================//convert address to urlurl url = new URL (path);// Get HTTP connection HttpURLConnection conn = (httpurlconnection) url.openconnection ()//Set the request mode of the connection Conn.setrequestmethod ("get") ;//IMPORTANT: Request the server download part of the file, specify the location of the file Conn.setrequestproperty ("Range", "bytes=" + StartIndex + "-" + EndIndex); System.out.println ("Thread:" + threadId + "real start Download progress:" + startIndex);//Set timeout time conn.setreadtimeout (5000);//Get the status code of the server, 200 indicates that all requested resources are responding = = = ok,206 The requested portion of the resource is responding = = = Okint Code = conn.getresponsecode (); System.out.println ("code:" + code), if (code = = 206) {//returns the file stream at the specified location inputstream is = Conn.getinputstream ();//Create a temporary file Ra Ndomaccessfile RAF = new Randomaccessfile (SD + "/" + filename, "RWD");//move pointer to the specified file location, Raf.seek (startIndex);// Create an intermediate buffer byte array byte[] buffer = NEW byte[1024];//read file size int length = 0;//Defines the length of data that has been downloaded, the record used as a breakpoint download ========================= the breakpoint record operation ======================= ========int downlodetotal = 0;//Loop writes while (length = is.read (buffer))! =-1) {//define a record thread's record file ========================= break Point record operation ===============================randomaccessfile historyfile = new Randomaccessfile (sd+ "/" + threadId + ". txt", " RWD ");//write data to the file raf.write (buffer, 0, length);//Record the length of the downloaded file Downlodetotal + = length;//Add the length of the downloaded file and the start read location, Get the file location that has been read Historyfile.write ((downlodetotal + StartIndex + ""). GetBytes ()); Historyfile.close ();//================= ======== Breakpoint record Operation ===============================//keep synchronized update synchronized (mainactivity.this) {// Add the size of the read file for each thread to the download progress on the Progresstemp + = length;//Update interface Progress The length of the progress bar pb.setprogress (progresstemp);// Special Case ProgressBar progressdialog//is a new UI that can be directly in a child thread, with the internal code having a special handling//use of message.obtain (); Reducing the creation of the message object                                                        message msg = Message.obtain (); msg.what = Progress_number_change;handler.sendmessage (msg);}} Is.close (); Raf.close (); System.out.println ("Thread:" + threadId + "Download complete ..."); "} else {System.out.println ("thread:" + threadid+ "Download failure please re-download ...");//Send information to Message Processor MSG = new Message (); msg.what = D Ownlode_error;handler.sendmessage (msg);}} catch (Exception e) {//TODO auto-generated catch Blocke.printstacktrace ();} finally {synchronized (mainactivity.this) {/ /number of thread changes operation runningthread--;//if the currently surviving thread is 0, perform a progress file uniform destroy operation if (Runningthread = = 0) {//If the download is complete, clear the Progress file for (int threadindex = 1; Threadindex <= ThreadCount; threadindex++) {//This is the file that corresponds to the thread file, the filename can be customized, and the convenience is that the thread id indicates file TEMP = new file (SD + "/" + threadindex+ ". txt");//Execute file Delete Temp.delete () except the operation;} System.out.println ("Download complete, delete progress file ...");//Send information to the Message Processor//Send information to the message Processor message msg = new Message (); msg.what = Downlode_success;handler.sendmessage (msg);}}}}}


Demo:

http://download.csdn.net/detail/u011936142/7428611




Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.