Development of Android programming to implement multithread breakpoint renewal Download Instance _android

Source: Internet
Author: User
Tags gettext

The example of this article describes the development of Android programming to implement multithread Breakpoint renewal Downloader. Share to everyone for your reference, specific as follows:

Using a multithreaded breakpoint to renew the downloader when downloading multiple threads concurrency can occupy more resources on the server side, to speed up the download, the download process to record the number of copies of each thread has been copied, if the download interruption, such as no signal disconnection, low power, and so on, this requires the use of a breakpoint to continue to pass the function, Continue downloading from the record location the next time you start, avoiding duplicate downloads. The database is used here to record the progress of the download.

Effect Chart :

Breakpoint Continuation

1. To record the download progress of each thread during the download process
2. Read the database before the start of each download, query for incomplete records, continue downloading, no more, create new records insert Database
3. Update the download progress in the database after each data is written to the file
4. Delete the download record in the database after the download is complete

Handler transfer data

This is primarily used to record percentages, and each download part of the data tells the main thread to record the time

1. The view created in the main thread can only be modified in the main thread, and other threads can only communicate through the main thread and change view data in the main thread
2. We use handler to handle this requirement

Create handler in main thread, rewrite Handlemessage () method

A new thread sends a message using handler, the main thread receives the message, and executes the Handlemessage () method

Dynamically generate new View

Multi-task downloads can be achieved

1. Create an XML file that will be generated by the view configuration well
2. Get the system services Layoutinflater to generate a new view

Copy Code code as follows:
Layoutinflater Inflater = (layoutinflater) getsystemservice (Layout_inflater_service);

3. Use the inflate (int resource, ViewGroup root) method to generate a new view
4. Call the AddView of a container in the current page and add the newly created view

Example

progress bar Style Download.xml

<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android= "http://schemas.android.com/apk/res/" Android "Android:layout_width=" Fill_parent "android:layout_height=" Wrap_content "> <linearlayout Android : orientation= "Vertical" android:layout_width= "fill_parent" android:layout_height= "Wrap_content" android:layout _weight= "1" > <!--progress bar style defaults to a circular progress bar, the horizontal progress bar needs to configure the Style property,? android:attr/progressbarstylehorizontal--> &L T ProgressBar android:layout_width= "fill_parent" android:layout_height= "20DP" style= "Android:attr/progres"? Sbarstylehorizontal "/> <textview android:layout_width=" wrap_content "android:layout_height=" W Rap_content "android:layout_gravity=" center "android:text=" 0% "/> </LinearLayout> <butto
    n android:layout_width= "40DP" android:layout_height= "40DP" android:onclick= "pause" android:text= "| |"

 /> </LinearLayout>

Top style Main.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" android:id= "@+id/root" > <textview android:layout_width= "fill_parent" Andr oid:layout_height= "wrap_content" android:text= "Please enter the download path"/> <linearlayout android:layout_width= "Fill_pa Rent "android:layout_height=" wrap_content "android:layout_marginbottom=" 30DP "> <edittext andr Oid:id= "@+id/path" android:layout_width= "fill_parent" android:layout_height= "Wrap_content" Android:singl Eline= "true" android:layout_weight= "1"/> <button android:layout_width= "Wrap_content" an droid:layout_height= "wrap_content" android:text= "Download" android:onclick= "Download"/> </linearlayou T> </LinearLayout> 

Mainactivity.java

public class Mainactivity extends activity {private Layoutinflater inflater;
  Private LinearLayout rootlinearlayout;
  Private EditText Pathedittext;
    @Override public void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
    Setcontentview (R.layout.main);
    Dynamically generate a new view, obtain the system service Layoutinflater, to generate a new view Inflater = (layoutinflater) getsystemservice (Layout_inflater_service);
    Rootlinearlayout = (linearlayout) Findviewbyid (r.id.root);
    Pathedittext = (edittext) Findviewbyid (R.id.path);
    After the form is created, query the database for unfinished tasks, and if so, create a component such as a progress bar, and continue downloading list<string> List = new Infodao (this). Queryundone ();
  for (String path:list) createdownload (path); /** * Download button * @param view */public void Download (view view) {String Path = http://192.168.1.199:8080/
    14_web/"+ pathedittext.gettext (). toString ();
  Createdownload (path); /** * Dynamic generation of New view * Initialize form data * @param path/private void Createdownload (String pATH) {//Get system services Layoutinflater to generate a new view layoutinflater Inflater = (layoutinflater) getsystemservice (Layout_inflat
    Er_service);
    LinearLayout linearlayout = (linearlayout) inflater.inflate (r.layout.download, NULL);
    LinearLayout childlinearlayout = (linearlayout) linearlayout.getchildat (0);
    ProgressBar ProgressBar = (ProgressBar) childlinearlayout.getchildat (0);
    TextView TextView = (TextView) childlinearlayout.getchildat (1);
    Button button = (button) linearlayout.getchildat (1);
      try {button.setonclicklistener (new MyListener (ProgressBar, TextView, Path));
    Invokes the addview of a container in the current page, adding the newly created view to Rootlinearlayout.addview (LinearLayout);
    catch (Exception e) {e.printstacktrace ();
    } Private Final class MyListener implements Onclicklistener {private ProgressBar ProgressBar;
    Private TextView TextView;
    private int fileLen;
    Private Downloader downloader;
    private String name; /** * Perform download * @param proGressbar//progress bar * @param textView//percent * @param path//download file path/public MyListener (ProgressBar progress
      Bar, TextView TextView, String path) {this.progressbar = ProgressBar;
      This.textview = TextView;
      Name = Path.substring (Path.lastindexof ("/") + 1);
      Downloader = new Downloader (Getapplicationcontext (), handler);
      try {downloader.download (path, 3);
        catch (Exception e) {e.printstacktrace ();
        Toast.maketext (Getapplicationcontext (), "exception occurred during download", 0). Show ();
      throw new RuntimeException (e); }//handler Transfer Data private Handler Handler = new Handler () {@Override public void Handlemessage (Me Ssage msg) {switch (msg.what) {case 0://Get the size of the file FileLen = Msg.getdata (). Getin
            T ("FileLen");
            Set the maximum scale of the progress bar: Setmax () Progressbar.setmax (FileLen);
          Break Case 1://get current Download total int done = msG.getdata (). GetInt ("Done");
            Percentage of current progress Textview.settext (name + "T" + done * 100/filelen + "%");
            The progress bar sets the current progress: setprogress () progressbar.setprogress (done);
              if (done = = FileLen) {Toast.maketext (Getapplicationcontext (), name + "Download Complete", 0). Show ();
            Exit the progress bar after the download completes Rootlinearlayout.removeview (View) progressbar.getparent (). GetParent ());
        } break;
    }
      }
    };
      /** * Pause and resume download * * public void OnClick (View v) {Button Pausebutton = (Button) v; if ("| |").
        Equals (Pausebutton.gettext ())) {downloader.pause ();
      Pausebutton.settext ("▶");
        else {downloader.resume ();
      Pausebutton.settext ("| |");

 }
    }
  }
}

Downloader.java

public class Downloader {private int done;
  Private Infodao DAO;
  private int fileLen;
  Private Handler Handler;
  Private Boolean ispause;
    Public Downloader (context context, Handler Handler) {dao = new Infodao (context);
  This.handler = handler; /** * Multithreading Download * @param path Download path * @param How many threads thcount need to be opened * @throws Exception/public void download
    (String path, int thcount) throws Exception {URL url = new URL (path);
    HttpURLConnection conn = (httpurlconnection) url.openconnection ();
    Set timeout time conn.setconnecttimeout (3000);
      if (conn.getresponsecode () = = FileLen = Conn.getcontentlength ();
      String name = path.substring (Path.lastindexof ("/") + 1);
      File File = new file (Environment.getexternalstoragedirectory (), name);
      Randomaccessfile RAF = new Randomaccessfile (file, "RWS");
      Raf.setlength (FileLen);
      Raf.close ();
      Handler sends a message, the main thread receives the message, gets the length of the data msg = new messages (); Msg.what = 0;
      Msg.getdata (). Putint ("FileLen", FileLen);
      Handler.sendmessage (msg);
      Calculates the number of bytes downloaded per thread int partlen = (FileLen + thCount-1)/thcount;
    for (int i = 0; i < thcount i++) new Downloadthread (URL, file, Partlen, i). Start ();
    else {throw new illegalargumentexception ("404 Path:" + path);
    } Private Final class Downloadthread extends Thread {private URL url;
    private file file;
    private int Partlen;
    private int id;
      Public downloadthread (URL url, file file, int partlen, int id) {this.url = URL;
      This.file = file;
      This.partlen = Partlen;
    This.id = ID; /** * Write operation/public void run () {//To determine if there was a last unfinished task info info = dao.query (url.tostring (), ID
      );
      if (info!= null) {//If there is, read the current thread has downloaded the amount done = = Info.getdone ();
        else {//if not, create a new record deposit info = new info (url.tostring (), ID, 0);
      Dao.insert (info);
   }   int start = ID * partlen + info.getdone ();
      Start position = + Download int end = (id + 1) * PARTLEN-1;
        try {HttpURLConnection conn = (httpurlconnection) url.openconnection ();
        Conn.setreadtimeout (3000);
        Gets the data at the specified location, range if the range of data is exceeded on the server, and the end of the server data is quasi conn.setrequestproperty ("range", "bytes=" + Start + "-" +);
        Randomaccessfile RAF = new Randomaccessfile (file, "RWS");
        Raf.seek (start);
        Start reading and writing data inputstream in = Conn.getinputstream ();
        byte[] buf = new byte[1024 * 10];
        int Len;
              while (len = In.read (buf))!=-1) {if (ispause) {//Lock this thread with a line lock synchronized (DAO) {
              try {dao.wait ();
              catch (Interruptedexception e) {e.printstacktrace ();
          }} raf.write (buf, 0, Len);
          Done by + = Len;
          Info.setdone (Info.getdone () + len);
  Record the amount of data that each thread has downloaded        Dao.update (info);
          The new thread sends the message with handler, and the main thread receives the message msg = new messages ();
          Msg.what = 1;
          Msg.getdata (). Putint ("Done");
        Handler.sendmessage (msg);
        } in.close ();
        Raf.close ();
      Delete Download Records Dao.deleteall (Info.getpath (), fileLen);
      catch (IOException e) {e.printstacktrace ();
  "}}//Pause download public void pause () {ispause = true;
    //Continue downloading public void resume () {ispause = false;
    Restores all threads synchronized (dao) {Dao.notifyall ();

 }
  }
}

Dao:

Dbopenhelper:

public class Dbopenhelper extends Sqliteopenhelper {public
  dbopenhelper (context) {
    Super Download.db ", NULL, 1);
  }
  @Override public
  void OnCreate (Sqlitedatabase db) {
    db.execsql ("CREATE TABLE Info" (Path VARCHAR (1024), Thid Integer, done integer, PRIMARY KEY (Path, thid)) ";
  }
  @Override public
  void Onupgrade (sqlitedatabase db, int oldversion, int newversion) {
  }
}

Infodao:

public class Infodao {private Dbopenhelper helper;
  Public Infodao {helper = new Dbopenhelper (context);
    public void Insert (info info) {Sqlitedatabase db = Helper.getwritabledatabase (); Db.execsql ("INSERT into Info" (path, Thid, done) VALUES (?,?,?), new object[] {Info.getpath (), Info.getthid (), Info.getdo
  NE ()});
    public void Delete (String path, int thid) {Sqlitedatabase db = Helper.getwritabledatabase (); Db.execsql ("DELETE from info WHERE path=?")
  And thid=? ", new object[] {path, thid});
    public void Update (info info) {Sqlitedatabase db = Helper.getwritabledatabase (); Db.execsql ("UPDATE info SET done=?") WHERE path=?
  And thid=? ", new object[] {info.getdone (), Info.getpath (), Info.getthid ()});
    Public Info Query (String path, int thid) {Sqlitedatabase db = Helper.getwritabledatabase (); Cursor C = db.rawquery ("Select Path, Thid, done from info WHERE path=?") And thid=? ", new string[] {path, string.valueof(Thid)});
    info info = null;
    if (C.movetonext ()) info = new info (c.getstring (0), C.getint (1), C.getint (2));
    C.close ();
  return info;
    public void DeleteAll (String path, int len) {Sqlitedatabase db = Helper.getwritabledatabase ();
    Cursor C = db.rawquery ("Select SUM (done) from info WHERE path=?", new string[] {path});
      if (C.movetonext ()) {int result = C.getint (0);
    if (result = = Len) db.execsql ("DELETE from info WHERE path=?", new object[] {path});
    } public list<string> Queryundone () {Sqlitedatabase db = Helper.getwritabledatabase ();
    Cursor C = db.rawquery ("Select DISTINCT path from info", NULL);
    list<string> pathlist = new arraylist<string> ();
    while (C.movetonext ()) Pathlist.add (c.getstring (0));
    C.close ();
  return pathlist;

 }
}

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

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.