The principle and implementation _android of the Android breakpoint continuation

Source: Internet
Author: User
Tags time interval

The principle and implementation of Android breakpoint continuation

0. Foreword

In Android development, the continuation of the breakpoint sounds easy, click Pause when downloading a file, and click Start to continue downloading the file. But the real realization of the knowledge point is quite a lot, so today has time to achieve a bit, and to record.

1. Principle of continuation of breakpoint

In the local download process to use the database real-time storage to where the file is stored , so click to continue delivery, the HTTP GET request in the Setrequestproperty () method can tell the server, Where the data starts and where it ends. Randomaccessfile's Seek () method also supports writing at any location in the file while the local file is being written. At the same time, the progress of the child thread is told by broadcast to the Processbar.

2. Activity's button response

When the Start button is clicked, the URL is written in the object info of the FileInfo class and passed through the intent to the service. This uses setaction () to distinguish between the Start button and the pause button.

public class FileInfo implements serializable{ 
  private String URL;//url 
  private int length;//length or end position 
  private int start; Start position 
  Private int now;//Current Progress 
//construction method, Set/get 
//Start button logic, stop logic roughly the same 
Strat.setonclicklistener ( New View.onclicklistener () { 
   @Override public 
   void OnClick (view view) { 
    Intent Intent = new Intent ( Mainactivity.this,downloadservice.class); 
    Intent.setaction (Downloadservice.action_start); 
    Intent.putextra ("FileUrl", info); 
    StartService (intent); 
  } 

3. Get file size in child threads in service

In the Onstartcommand () in the service, remove the FileInfo object from the intent and, if it is the start command, open a thread that, depending on the URL, gets the size of the file to download. Writes the size to the object and returns the service via handler, creating a local file of the same size locally. The pause command will be mentioned at the end.

public void Run () {httpurlconnection urlconnection = null; 
      Randomaccessfile randomfile = null; 
        try {URL url = new URL (fileinfo.geturl ()); 
        URLConnection = (httpurlconnection) url.openconnection (); 
        Urlconnection.setconnecttimeout (3000); 
        Urlconnection.setrequestmethod ("get"); 
        int length =-1; if (urlconnection.getresponsecode () = = HTTPSTATUS.SC_OK) {//Get file length = Urlconnection.getconten 
        Tlength (); 
        } if (length <= 0) {return; 
        //Create the same size local file, dir = new file (Download_path); 
        if (!dir.exists ()) {Dir.mkdir (); 
        File File = new file (dir, file_name); 
        Randomfile = new Randomaccessfile (file, "RWD"); 
        Randomfile.setlength (length); 
        Length is given to FileInfo object fileinfo.setlength. The object is passed to the service mhandle.obtainmessage (0, FileInfo) by handler. SendtotargET (); 
      catch (Exception e) {e.printstacktrace ();  finally {///Stream recovery logic is slightly}}}

4. Database Operation encapsulation

In the Handlemessage () method of the service, get the FileInfo object with the length attribute and use the custom Downloadutil class for the specific file download logic. The context is passed here because the database processing operation needs to be used.

Downloadutil = new Downloadutil (downloadservice.this,info);

Downloadutil.download ();

Here is a database operation interface Threaddao, internal there are additions and deletions and other logic , used to record the download task information. Customizing a Threaddaoimpl class to implement the logic here, the internal database creates the logic of the custom class that inherits the Sqliteopenhelper, and it is simpler to create an instance in the constructor method of the Threaddaoimpl class. complete the encapsulation of the underlying database operation.

Public interface Threaddao { 
  //Insert a data public 
  void Insert (FileInfo info); 
  Deletes a data public 
  void Delete (String URL) based on the URL 
  ; Updates a progress public 
  void Update (String Url,int finished) based on the URL; 
  Finds a data public list<fileinfo> get 
  (String URL) based on the URL; 
  Whether there is a public 
  boolean isexits (String URL); 

5. Specific File download logic

public class Downloadutil {//construction method slightly public void download () {list<fileinfo> lists = Threaddao.get (fileinf 
    O.geturl ()); 
    FileInfo info = null; 
    if (lists.size () = = 0) {//First download, create child thread download new Mythread (FileInfo). Start (); 
      }else{//middle Start info = lists.get (0); 
    New Mythread (Info). Start (); 
    } class Mythread extends thread{private FileInfo info = null; 
    Public Mythread (FileInfo threadinfo) {this.info = Threadinfo; @Override public void Run () {//Add thread information to the database if (!threaddao.isexits (Info.geturl ())) {Threa 
      Ddao.insert (info); 
      } httpurlconnection urlconnection = null; 
      Randomaccessfile Randomfile =null; 
      InputStream inputstream = null; 
        try {URL url = new URL (info.geturl ()); 
        URLConnection = (httpurlconnection) url.openconnection (); 
        Urlconnection.setconnecttimeout (3000); Urlconnection.setrequestmethod ("Get"); 
        Set download location int start = Info.getstart () + Info.getnow (); 
 
        Urlconnection.setrequestproperty ("Range", "bytes=" + Start + "-" + info.getlength ()); 
        Sets the file write location of filename = new file (download_path,file_name); 
        Randomfile = new Randomaccessfile (file, "RWD"); 
 
        Randomfile.seek (start); 
        Broadcast to activity Intent Intent = new Intent (action_update); 
 
        Finished + + Info.getnow (); if (urlconnection.getresponsecode () = = Httpstatus.sc_partial_content) {//Get file stream InputStream = Urlcon 
          Nection.getinputstream (); 
          byte[] buffer = new BYTE[512]; 
          int len =-1; 
          Long time = System.currenttimemillis (); 
            while (len = inputstream.read (buffer))!=-1) {//write file Randomfile.write (Buffer,0,len); 
            Send the progress to activity finished = Len; Look at the time interval, the interval is greater than 500ms again if (System.currenttimemillis ()-Time >5{time = System.currenttimemillis (); 
              Intent.putextra ("Now", finished *100/fileinfo.getlength ()); 
            Context.sendbroadcast (Intent); 
              //Determine if it is a paused state if (ispause) {threaddao.update (Info.geturl (), finished); Return 
        End Loop}//delete thread information Threaddao.delete (Info.geturl ()); 
      }}catch (Exception e) {e.printstacktrace ();  }finally {//Recycle work Abbreviated}}}}

It also refers to the use of a custom Downloadutil class for specific file download logic, which is also the most critical part of creating a Threaddaoimpl instance in the constructor of the class. and in download () through the operation of the database query to determine whether it is the first time to start the download task , if it is, then open a child thread mythread to download the task, otherwise the progress information from the database, and the information passed to Mythread.

In Mythread, through the Info.getstart () + info.getnow () settings to start the download location, if it is the first download two will be 0, if it is suspended and then download, then Info.getnow () will take out a value of 0, This value is from the database store. Use Setrequestproperty to tell the server where to start passing data, where to end, and local use of the Randomaccessfile seek () method for local storage of data. Use broadcasts to pass a percentage of progress to activity,activity and then change Processbar for UI adjustments.

The key point here is to call Downloadutil.ispause = True in the service afterthe user clicks the pause, so the top while loop ends, stops downloading, and saves the progress value through the database update (). This value is removed at the time of continuation, the download task request for the server initiating the file start point is restarted, and the write operation is also continued at the appropriate location of the local file.

6. The effect is shown below


Thank you for reading, I hope to help you, thank you for your support for this site!

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.