How to implement multithreading download files with Android _android

Source: Internet
Author: User
Tags gettext

This article is an example of how Android implements multithreaded download files. Share to everyone for your reference. Specifically as follows:

Multithreading download is probably the idea is to implement the file segmentation through the Range property, and then use Randomaccessfile to read and write files, and eventually merged into a file

First look at the effect chart:

Create Engineering Threaddemo

First layout file Threaddemo.xml

<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android= "http://schemas.android.com/apk/res/" 
  Android "android:orientation=" vertical "android:layout_width=" fill_parent "android:layout_height=" Fill_parent " > <textview android:layout_width= "fill_parent" android:layout_height= wrap_content "android:text=" Download address "/> <textview android:id=" @+id/downloadurl "android:layout_width=" Fill_parent "android:layout_height=" "Wrap_content" android:lines= "5"/> <textview android:layout_width= "Fill_parent" Android:layout_heig ht= "wrap_content" android:text= "thread Count"/> <edittext android:id= "@+id/downloadnum" 
  Fill_parent "android:layout_height=" wrap_content "/> <progressbar android:id=" @+id/downloadProgressBar " Android:layout_width= "Fill_parent" style= "Android:attr/progressbarstylehorizontal" android:layout_height= "WRAP_" Content "/> <textview 
  Android:id= "@+id/downloadinfo" android:layout_width= "fill_parent" android:layout_height= "Wrap_content" Andr oid:text= "Download Progress 0"/> <button android:id= "@+id/downloadbutton" android:layout_width= "Wrap_content" Andr

 oid:layout_height= "Wrap_content" android:text= "Start download"/> </LinearLayout>
<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android= "http://schemas.android.com/apk/res/"  Android "android:orientation=" vertical "android:layout_width=" fill_parent "android:layout_height=" Fill_parent "
> <textview android:layout_width= "fill_parent" android:layout_height= "wrap_content" android:text= "Download Address"/> <textviewandroid:id= "@+id/downloadurl" android:layout_width= "fill_parent" android:layout_height= "Wrap_content" "android:lines=" 5 "/> <textview android:layout_width=" fill_parent "android:layout_height=" Wrap_content " android:text= "Thread Count"/> <edittextandroid:id= "@+id/downloadnum" android:layout_width= "Fill_parent" Android: layout_height= "Wrap_content"/> <progressbarandroid:id= "@+id/downloadprogressbar" Fill_parent "style=" "Android:attr/progressbarstylehorizontal" android:layout_height= "Wrap_content"/> < Textviewandroid:id= "@+id/downloadinfo" android:layout_width= "fill_parent" android:layout_height= "WR"Ap_content "android:text=" Download Progress 0 "/> <buttonandroid:id=" @+id/downloadbutton "android:layout_width=" Wrap_ 

 Content "android:layout_height=" wrap_content "android:text=" Start download/> </LinearLayout>

Main interface acitivity

public class Threaddownloaddemo extends activity {private TextView downloadurl; 
  Private EditText Downloadnum; 
  Private Button Downloadbutton; 
  Private ProgressBar Downloadprogressbar; 
  Private TextView Downloadinfo; 
  private int downloadedsize = 0; 
  private int fileSize = 0; 
  Private long downloadtime; 
    @Override public void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); 
    Setcontentview (R.layout.threaddemo); 
    DownloadURL = (TextView) Findviewbyid (R.id.downloadurl); Downloadurl.settext ("http://file16.top100.cn/201105110911/AA5CC27CBE34DEB50A194581D1300881/Special_323149/%E8% 
    8d%b7%e5%a1%98%e6%9c%88%e8%89%b2.mp3 "); 
    Downloadnum = (edittext) Findviewbyid (r.id.downloadnum); 
    Downloadinfo = (TextView) Findviewbyid (r.id.downloadinfo); 
    Downloadbutton = (Button) Findviewbyid (R.id.downloadbutton); 
    Downloadprogressbar = (ProgressBar) Findviewbyid (R.id.downloadprogressbar); Downloadprogressbar.setvisibilitY (view.visible); 
    Downloadprogressbar.setmax (100); 
    Downloadprogressbar.setprogress (0); 
        Downloadbutton.setonclicklistener (New Onclicklistener () {public void OnClick (View v) {download (); 
      Downloadtime = Systemclock.currentthreadtimemillis (); 
  } 
    }); 
        private void Download () {//Get SD card directory String Dowloaddir = Environment.getexternalstoragedirectory () 
    + "/threaddemodownload/"; 
    File File = new file (Dowloaddir); 
    Create the download directory if (!file.exists ()) {file.mkdirs (); //Read download thread number, if NULL, single-threaded download int downloadtn = integer.valueof ("". Equals (Downloadnum.gettext (). toString ()) ? 
    "1": Downloadnum.gettext (). toString ()); 
    String fileName = "Hetang.mp3"; 
    Set the download button to unavailable downloadbutton.setclickable (false) before starting the download; 
    The progress bar is set to 0 downloadprogressbar.setprogress (0); Startup file download thread new Downloadtask ("Http://file16.top100.cn/201105110911/AA5CC27CBE34DEB50A194581D1300881/Special_323149/%e8%8d%b7%e5%a1%98%e6%9c%88%e8%89%b2.mp3 ", Integer. valueof (DOWNLOADTN), Dowloaddir + fileName). Start (); Handler Handler = new Handler () {@Override public void Handlemessage (msg) {//When an update view message is received 
      , calculate the percentage of completed downloads while updating the progress bar information int progress = (double.valueof (downloadedsize * 1.0/filesize *)). Intvalue (); 
        if (progress = =) {downloadbutton.setclickable (true); Downloadinfo.settext ("Download complete!") 
        "); Dialog Mdialog = new Alertdialog.builder (threaddownloaddemo.this). Settitle ("hint info"). Setmessage ("Download complete Into, the total when: "+ (Systemclock.currentthreadtimemillis ()-downloadtime) +" milliseconds "). Setnegativebutton (" OK ", new DIALOGINTERFAC 
              E.onclicklistener () {@Override public void OnClick (Dialoginterface dialog, int which) { 
            Dialog.dismiss (); 
        ). Create (); 
      Mdialog.show (); else {Downloadinfo.settext ("current progress: "+ progress +"% "); 
    } downloadprogressbar.setprogress (progress); 
  } 
  }; 
    public class Downloadtask extends Thread {private int blockSize, Downloadsizemore; 
    private int threadnum = 5; 
    String urlstr, Threadno, FileName; 
      Public Downloadtask (string urlstr, int threadnum, string fileName) {this.urlstr = Urlstr; 
      This.threadnum = Threadnum; 
    This.filename = FileName; 
      @Override public void Run () {filedownloadthread[] FDs = new Filedownloadthread[threadnum]; 
        try {URL url = new URL (urlstr); 
        URLConnection conn = Url.openconnection (); 
        Prevent return-1 inputstream in = Conn.getinputstream (); 
        Gets the total size of the download file FileSize = Conn.getcontentlength (); 
        LOG.I ("BB", "======================filesize:" +filesize); 
        Calculate the amount of data per thread to download blockSize = Filesize/threadnum; 
    The percentage calculation error Downloadsizemore = (fileSize% threadnum) is resolved;    File File = new file (fileName); 
          for (int i = 0; i < threadnum i++) {log.i ("BB", "======================i:" +i); Start the thread, download the part that you need to download separately filedownloadthread FDT = new Filedownloadthread (URL, file, I * blockSize, (i + 1) * block 
          SIZE-1); 
          Fdt.setname ("Thread" + i); 
          Fdt.start (); 
        Fds[i] = FDT; 
        Boolean finished = false; 
          while (!finished) {//downloadedsize the remainder of the divide by the first = Downloadsizemore; 
          Finished = true; 
            for (int i = 0; i < fds.length i++) {downloadedsize + = Fds[i].getdownloadsize (); 
            if (!fds[i].isfinished ()) {finished = false; 
          } handler.sendemptymessage (0); 
        Thread pauses for one second sleep (1000); 
      } catch (Exception e) {e.printstacktrace (); }}} public class Threaddownloaddemo extends activity {private TeXtview DownloadURL;
Private EditText Downloadnum;
Private Button Downloadbutton;
Private ProgressBar Downloadprogressbar;
Private TextView Downloadinfo;
private int downloadedsize = 0;
private int fileSize = 0;
Private long downloadtime; @Overridepublic void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (
R.layout.threaddemo);
DownloadURL = (TextView) Findviewbyid (R.id.downloadurl); Downloadurl.settext ("http://file16.top100.cn/201105110911/AA5CC27CBE34DEB50A194581D1300881/Special_323149/%E8%
8d%b7%e5%a1%98%e6%9c%88%e8%89%b2.mp3 ");
Downloadnum = (edittext) Findviewbyid (r.id.downloadnum);
Downloadinfo = (TextView) Findviewbyid (r.id.downloadinfo);
Downloadbutton = (Button) Findviewbyid (R.id.downloadbutton);
Downloadprogressbar = (ProgressBar) Findviewbyid (R.id.downloadprogressbar);
Downloadprogressbar.setvisibility (view.visible);
Downloadprogressbar.setmax (100);
Downloadprogressbar.setprogress (0); Downloadbutton.setonclicklistener (New OnclicklisteneR () {public void OnClick (View v) {download (); downloadtime = Systemclock.currentthreadtimemillis ();}}); private void Download () {//Get SD card directory String Dowloaddir = environment.getexternalstoragedirectory () + "/
Threaddemodownload/";
File File = new file (Dowloaddir); Create download directory if (!file.exists ()) {file.mkdirs ();} Number of Read download threads, if null, single-threaded download int downloadtn = integer.valueof ("". Equals (Downloadnum.gettext (). toString ())?
1 ": Downloadnum.gettext (). toString ());
String fileName = "Hetang.mp3";
Set the download button to unavailable downloadbutton.setclickable (false) before starting the download;
The progress bar is set to 0 downloadprogressbar.setprogress (0); Startup file download thread new Downloadtask ("Http://file16.top100.cn/201105110911/AA5CC27CBE34DEB50A194581D1300881/Special_
323149/%e8%8d%b7%e5%a1%98%e6%9c%88%e8%89%b2.mp3 ", integer.valueof (DOWNLOADTN), Dowloaddir + fileName). Start ();  Handler Handler = new Handler () {@Overridepublic void handlemessage (Message msg) {//When you receive the update view messages, calculate the percentage of completed downloads, and update the progress bar information int Progress = (double.valueof (downloadedsize * 1.0/filesize *)). intValue (); if (progress = =) {downloadbutton.setclickable (true); Downloadinfo.settext ("Download complete!")
"); Dialog Mdialog = new Alertdialog.builder (threaddownloaddemo.this). Settitle ("hint info"). Setmessage ("Download complete, total when:" + ( Systemclock.currentthreadtimemillis ()-downloadtime) + "millisecond"). Setnegativebutton ("OK", new Dialoginterface.onclicklistener () {@Overridepublic void OnClick (dialoginterface dialog, int which) {Dialog.dismiss ();}}).
Create ();
Mdialog.show ();
else {Downloadinfo.settext ("Current Progress:" + progress + "%");}
Downloadprogressbar.setprogress (progress); 
}
};
public class Downloadtask extends Thread {private int blockSize, downloadsizemore; private int threadnum = 5;
String urlstr, Threadno, FileName; Public Downloadtask (string urlstr, int threadnum, string fileName) {this.urlstr = urlstr; this.threadnum = threadnum; thi
S.filename = FileName; @Overridepublic void Run () {filedownloadthread[] FDs = new Filedownloadthread[threadnum]; try {URL url = new URL (urlstr
); URLConnection conn = url.openconnection();
Prevent return-1 inputstream in = Conn.getinputstream ();
Gets the total size of the download file FileSize = Conn.getcontentlength ();
LOG.I ("BB", "======================filesize:" +filesize);
Calculate the amount of data per thread to download blockSize = Filesize/threadnum;
The percentage calculation error Downloadsizemore = (fileSize% threadnum) is resolved;
File File = new file (fileName);
for (int i = 0; i < threadnum i++) {log.i ("BB", "======================i:" +i);
Start the thread, download separately the part filedownloadthread FDT = new Filedownloadthread (URL, file, I * blockSize, (i + 1) * blockSize-1);
Fdt.setname ("Thread" + i);
Fdt.start ();
Fds[i] = FDT;
Boolean finished = false; while (!finished) {//downloadedsize the remainder of the division = Downloadsizemore; finished = true; for (int i = 0; i < fds.length; i+ +) {downloadedsize + = Fds[i].getdownloadsize (); if (!fds[i].isfinished ()) {finished = false;}} HANDLER.SENDEMPTYMESSAG
E (0);
Thread pauses for one second sleep (1000);
The catch (Exception e) {e.printstacktrace ();}} 

 }
}

The start thread here splits the file into several parts, each part starts a thread to download the data
The thread that downloaded the file

public class Filedownloadthread extends thread{private static final int buffer_size=1024; 
  Private URL URL; 
  private file file; 
  private int startposition; 
  private int endposition; 
  private int curposition; 
  Identifies whether the current thread is downloading complete private Boolean finished=false; 
  private int downloadsize=0; 
    Public Filedownloadthread (URL url,file file,int startposition,int endposition) {this.url=url; 
    This.file=file; 
    This.startposition=startposition; 
    This.curposition=startposition; 
  This.endposition=endposition; 
    @Override public void Run () {Bufferedinputstream bis = null;                         
    Randomaccessfile fos = null; 
    byte[] buf = new Byte[buffer_size]; 
    URLConnection con = null; 
      try {con = url.openconnection (); 
      Con.setallowuserinteraction (TRUE); 
      Set the current thread download start point con.setrequestproperty ("Range", "bytes=" + startposition + "-" + endposition); LOG.I ("BB", Thread.CurrentThread (). GetName () + " Bytes= "+ startposition +"-"+ endposition"; 
      Random Read and write to files using Randomaccessfile in Java fos = new Randomaccessfile (file, rw); 
      Sets the starting position of the write file Fos.seek (startposition);  
      bis = new Bufferedinputstream (Con.getinputstream ());         
        Start the loop to read and write files as streaming while (Curposition < endposition) {int len = bis.read (buf, 0, buffer_size); 
        if (len = = 1) {break; 
        } fos.write (buf, 0, Len); 
        Curposition = curposition + len; 
        if (Curposition > Endposition) {downloadsize+=len-(curposition-endposition) + 1; 
        else {Downloadsize+=len; 
      }///download complete set to True this.finished = true; 
      Bis.close (); 
    Fos.close (); 
    catch (IOException e) {e.printstacktrace (); 
  } public boolean isfinished () {return finished; 
  public int getdownloadsize () {return downloadsize; }} public class FiledownLoadthread extends thread{private static final int buffer_size=1024; private URL url; private File file; private int star
Tposition;
private int endposition;
private int curposition;//identifies whether the current thread downloads the complete private boolean finished=false;
private int downloadsize=0;
Public Filedownloadthread (URL url,file file,int startposition,int endposition) {this.url=url;
This.startposition=startposition;
This.curposition=startposition;
This.endposition=endposition;
@Overridepublic void Run () {Bufferedinputstream bis = null;
Randomaccessfile fos = null;
byte[] buf = new Byte[buffer_size];
URLConnection con = null; try {con = url.openconnection (); Con.setallowuserinteraction (true);//Set the starting and ending point of the current thread download Con.setrequestproperty ("Range", "
Bytes= "+ startposition +"-"+ endposition";
LOG.I ("BB", Thread.CurrentThread (). GetName () + "bytes=" + startposition + "-" + endposition);
Random Read and write to files using Randomaccessfile in Java fos = new Randomaccessfile (file, rw);
Sets the starting position of the write file Fos.seek (startposition); bis = newBufferedinputstream (Con.getinputstream ()); 
Start loop Read and write file as stream (Curposition < endposition) {int len = bis.read (buf, 0, buffer_size); if (len = = 1) {break;}
Fos.write (buf, 0, Len);
Curposition = curposition + len;
if (Curposition > Endposition) {downloadsize+=len-(curposition-endposition) + 1;} else {Downloadsize+=len;}}
Download complete set to True this.finished = true;
Bis.close ();
Fos.close ();
catch (IOException e) {e.printstacktrace ();}}

 public Boolean isfinished () {return finished.} public int getdownloadsize () {return downloadsize;}}

Here, the Randomaccessfile seek method is used to locate the corresponding location and record the download amount in real time.
Of course, this requires networking and access to the SD card, so add the appropriate permissions

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

This will be OK below you can see the problem of the continuation of the breakpoint. Waiting to be tested ~ ~

I hope this article will help you with your Android program.

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.