Android Development-Multi-threaded download plus breakpoint continuation

Source: Internet
Author: User
Tags file url

File download in the app is also used a lot, the general version of the update to use the file to download to do processing, has seen a lot of great God has had this aspect of the blog, today I also to practice, write the general, but also ask you to make more comments, common progress. Main ideas:

1. Multi-Threaded Download:

First, by downloading the number of bus path to divide the download area of the file: the use of int range = Filesize/threadcount; get each download volume; The position of each segment is I * range to (i + 1) * rang-1, note that the last paragraph is to fil esize-1;

The download file is segmented by the range field of the HTTP protocol;

The Java class Randomaccessfile can implement random access to the file, and use the Seek method to locate the specified location of the file;

The stream can be read and written by HttpURLConnection, and the storage of the file is realized.

Use handler to deliver the downloaded information outward during the download process.

2. Continuation of the breakpoint:

For each thread to use a Downloadinfo class to save the downloaded information, update the information to the database each time it is downloaded (I have thought about updating it only when the download is paused, but then the information cannot be saved when our process is killed). To access the database before downloading, if there is a record, if there is no initialization of the first download, if there is a record but the download file does not exist, delete the records in the database for the first download initialization, if there is a record and the file exists, the information is taken from the database.

Implementing the effect of your own encapsulated class provides a way to start, pause, delete, and re-download. Haven't had time to put on the project CSDN, to everyone a Baidu cloud disk: Http://pan.baidu.com/s/1dD1Xo8T

The structure of the main classes are:

1) Downloadhttptool: Use HTTP protocol for network download class

2) Downlaodsqltool, Downloadhelper: Database Related Operations class

3) Downloadinfo: Download Information Save class

4) Downloadutil: class that encapsulates the download method and provides an external interface

Post Code: Downloadinfo class

Package Com.example.test;public class Downloadinfo {/** * save each download thread download information class * */private int threadid;//downloader idprivate int star tpos;//start point private int endpos;//end point private int compeletesize;//completion degree private String url;//download file URL address public downloadinfo (i NT ThreadId, int startpos, int endpos,int compeletesize, String url) {this.threadid = Threadid;this.startpos = startpos;th Is.endpos = endpos;this.compeletesize = Compeletesize;this.url = URL;} Public Downloadinfo () {}public String getUrl () {return URL;} public void SetUrl (String url) {this.url = URL;} public int GetThreadId () {return threadId;} public void Setthreadid (int threadId) {this.threadid = threadId;} public int Getstartpos () {return startpos;} public void Setstartpos (int startpos) {this.startpos = startpos;} public int Getendpos () {return endpos;} public void Setendpos (int endpos) {this.endpos = Endpos;} public int getcompeletesize () {return compeletesize;} public void setcompeletesize (int compeletesize) {this.compeletesize = compeletesize;} @OverriDepublic String toString () {return "Downloadinfo [threadid=" + ThreadId + ", startpos=" + startpos+ ", endpos=" + Endpos + ", compeletesize=" + compeletesize+ "]";}}
Downloadhelper class, creating our database file
Package Com.example.test;import Android.content.context;import Android.database.sqlite.sqlitedatabase;import android.database.sqlite.sqliteopenhelper;/** * Use database to record download information * @author Acer */public class Downloadhelper extends Sqliteopenhelper{private static final String sql_name = "download.db";p rivate static final int download_version=1;public Downloadhelper (Context context) {Super (context, sql_name, NULL, download_version);//TODO Auto-generated constructor stub}/**     * Create a download_info table store download information under the DOWNLOAD.DB database     *    /@Override public    void OnCreate ( Sqlitedatabase db) {        db.execsql ("CREATE Table Download_info (_id integer PRIMARY KEY autoincrement, thread_id integer , "                +" Start_pos integer, End_pos integer, compelete_size integer,url char);    }    @Override public    void Onupgrade (sqlitedatabase db, int oldversion, int newversion) {    }}
Downlaodsqltool the insertion and update of data to delete operations
Package Com.example.test;import Java.util.arraylist;import Java.util.list;import android.content.context;import Android.database.cursor;import android.database.sqlite.sqlitedatabase;/** * * Database Operations Tool Class */public class DownlaodSqlTool    {Private Downloadhelper dbhelper;    Public Downlaodsqltool (Context context) {DBHelper = new Downloadhelper (context); /** * Create specific information for download */public void Insertinfos (list<downloadinfo> infos) {sqlitedatabase databas        E = Dbhelper.getwritabledatabase (); for (Downloadinfo info:infos) {String sql = ' INSERT into Download_info (Thread_id,start_pos, End_pos,compelet            E_size,url) VALUES (?,?,?,?,?) "; Object[] Bindargs = {Info.getthreadid (), Info.getstartpos (), Info.getendpos (), Info.getcompeletesize ()            , Info.geturl ()};        Database.execsql (SQL, Bindargs); }}/** * get download Details */public list<downloadinfo> Getinfos (String urlstr) {list<downloadinfo> list = new arraylist<downloadinfo> ();        Sqlitedatabase database = Dbhelper.getwritabledatabase ();        String sql = "Select thread_id, Start_pos, End_pos,compelete_size,url from Download_info where url=?";        cursor cursor = database.rawquery (sql, new string[] {urlstr}); while (Cursor.movetonext ()) {Downloadinfo info = new Downloadinfo (cursor.getint (0), cursor.            GetInt (1), Cursor.getint (2), Cursor.getint (3), cursor.getstring (4));        List.add (info);    } return list; /** * Update the download information in the database */public void Updatainfos (int threadId, int compeletesize, String urlstr) {SQLi        Tedatabase database = Dbhelper.getwritabledatabase (); String sql = "Update download_info set compelete_size=?" where thread_id=?        and url=? ";        Object[] Bindargs = {compeletesize, threadId, urlstr};    Database.execsql (SQL, Bindargs); }/** * Close database */public VoiD closedb () {dbhelper.close (); /** * Delete data from database after download is complete */public void delete (String URL) {sqlitedatabase database = Dbhelper.getwrit        Abledatabase ();    Database.delete ("Download_info", "url=", new string[] {URL}); }}
Downloadhttptool for Web-downloaded classes
Package Com.example.test;import Java.io.file;import Java.io.inputstream;import java.io.randomaccessfile;import Java.net.httpurlconnection;import Java.net.url;import Java.util.arraylist;import Java.util.List;import Android.content.context;import Android.os.handler;import Android.os.message;import Android.util.Log;public class Downloadhttptool {/** * * Use HTTP protocol for multi-threaded Download concrete Practice class */private static final String TAG = DownloadHttpTool.class.getSimpleName () ;p rivate int threadcount;//thread number private String Urlstr;//url address private Context mcontext;private Handler mhandler;private list<downloadinfo> downloadinfos;//Save Download Information class private string localpath;//directory private string filename;//file name private int filesize;private downlaodsqltool sqltool;//file Information save database operation class Private enum Download_state {downloading, Pause, ready;// The enumeration represents the three states of the download}private download_state state = download_state.ready;//current download status private int globalcompelete = 0;// Total downloads for all threads public downloadhttptool (int threadcount, String urlstring,string LocalPath, string fIlename, Context context, Handler Handler) {super (); this.threadcount = Threadcount;this.urlstr = urlstring; This.localpath = Localpath;this.mcontext = Context;this.mhandler = Handler;this.filename = FileName;sqlTool = new Downlao Dsqltool (Mcontext);} Before you start the download, you need to call the Ready method to configure public void ready () {LOG.W (TAG, ' ready '); globalcompelete = 0;downloadinfos = Sqltool.getinfos ( URLSTR), if (downloadinfos.size () = = 0) {Initfirst ();} else {File file = new file (LocalPath + "/" + FileName); if (!file.exi STS ()) {sqltool.delete (URLSTR); Initfirst ();} else {fileSize = Downloadinfos.get (Downloadinfos.size ()-1). Getendpos () ; for (Downloadinfo Info:downloadinfos) {globalcompelete + = Info.getcompeletesize ();} LOG.W (TAG, "Globalcompelete:::" + Globalcompelete);}} public void Start () {LOG.W (TAG, "start"); if (Downloadinfos! = null) {if (state = = download_state.downloading) {return;} State = Download_state.downloading;for (Downloadinfo info:downloadinfos) {log.v (TAG, "Startthread"); new Downloadthread (Info.getthreadiD (), Info.getstartpos (), Info.getendpos (), Info.getcompeletesize (), Info.geturl ()). Start ();}} public void Pause () {state = Download_state.pause;sqltool.closedb ();} public void Delete () {compelete (); File File = new file (LocalPath + "/" + FileName); File.delete ();} public void Compelete () {sqltool.delete (URLSTR); Sqltool.closedb ();} public int GetFileSize () {return fileSize;} public int getcompeletesize () {return globalcompelete;} First download initializes private void Initfirst () {LOG.W (TAG, "Initfirst"); try {URL url = new URL (urlstr); HttpURLConnection connection = (httpurlconnection) url.openconnection (); connection.setconnecttimeout (5000); Connection.setrequestmethod ("GET"); fileSize = Connection.getcontentlength (); LOG.W (TAG, "fileSize::" + fileSize); File Fileparent = new file (LocalPath), if (!fileparent.exists ()) {Fileparent.mkdir ();} File File = new file (fileparent, FileName), if (!file.exists ()) {file.createnewfile ();} Local Access file Randomaccessfile accessfile = new Randomaccessfile (file, "RWD"); Accessfile.setlength (filesize); Accessfile.close (); Connection.disconnect ();} catch (Exception e) {e.printstacktrace ();} int range = Filesize/threadcount;downloadinfos = new arraylist<downloadinfo> (); for (int i = 0; i < ThreadCount -1; i++) {Downloadinfo info = new Downloadinfo (i, I * range, (i + 1) * range-1, 0, Urlstr);d Ownloadinfos.add (info);} Downloadinfo info = new Downloadinfo (threadCount-1, (threadCount-1) * range, fileSize-1, 0, urlstr);d Ownloadinfos.add (info); Sqltool.insertinfos (Downloadinfos);} Custom download thread private class Downloadthread extends thread {private int threadid;private int startpos;private int Endpos;privat e int compeletesize;private String urlstr;private int totalthreadsize;public downloadthread (int threadId, int startpos, I NT Endpos,int compeletesize, String urlstr) {this.threadid = Threadid;this.startpos = Startpos;this.endpos = EndPos;total Threadsize = endpos-startpos + 1;this.urlstr = Urlstr;this.compeletesize = compeletesize;} @Overridepublic void Run () {HttpURLConnection connection = null; Randomaccessfile Randomaccessfile = Null;inputstream is = null;try {randomaccessfile = new Randomaccessfile (LocalPath + "/ "+ FileName," RWD "); Randomaccessfile.seek (startpos + compeletesize); URL url = new URL (urlstr), connection = (httpurlconnection) url.openconnection (); connection.setconnecttimeout (5000); Connection.setrequestmethod ("GET"); Connection.setrequestproperty ("Range", "bytes=" + (Startpos + compeletesize) + "-" + Endpos); is = Connection.getinputstream (); byte[] buffer = new Byte[1024];int length = -1;while ((length = is.read (buffer) )! =-1) {randomaccessfile.write (buffer, 0, length); compeletesize + = length; Message message = Message.obtain (); message.what = Threadid;message.obj = Urlstr;message.arg1 = length; Mhandler.sendmessage (message); Sqltool.updatainfos (ThreadId, Compeletesize, URLSTR);  LOG.W (TAG, "Threadid::" + Threadid + "Compelete::" + compeletesize + "total::" + totalthreadsize); if (compeletesize >= totalthreadsize) {break;} if (state! = Download_state.downloading) {break;}}} catch (Exception e) {e.printstacktrace ();} finally {try {if (is! = null) {Is.close ();} Randomaccessfile.close (); Connection.disconnect ();} catch (Exception e) {e.printstacktrace ();}}}}
Downloadutils provides a method class for downloading the outward interface:
Package Com.example.test;import Android.annotation.suppresslint;import Android.content.context;import Android.os.asynctask;import android.os.handler;import Android.os.message;import android.util.Log;/** * Encapsulate the download method in this class * Provides download, pause, delete, and reset methods */public class Downloadutil {private Downloadhttptool mdownloadhttptool;private Ondownloadlistener ondownloadlistener;private int filesize;private int downloadedsize = 0; @SuppressLint ("Handlerleak") Private Handler Mhandler = new Handler () {@Overridepublic void Handlemessage (Message msg) {//TODO auto-generated method Stubsuper.handlem Essage (msg); int length = msg.arg1;synchronized (this) {//locking guarantee the correctness of the download downloadedsize + = length;} if (Ondownloadlistener! = null) {ondownloadlistener.downloadprogress (downloadedsize);} if (downloadedsize >= fileSize) {mdownloadhttptool.compelete (); if (ondownloadlistener! = null) { Ondownloadlistener.downloadend ();}}}; Public downloadutil (int threadcount, string filePath, String filename,string urlstring, Context context) {MdowNloadhttptool = new Downloadhttptool (threadcount, Urlstring,filepath, filename, context, mhandler);} Before the download begins, the async thread calls the Ready method to get the file size information, and then calls the Start method public void Start () {new asynctask<void, void, void> () {@ overrideprotected void Doinbackground (void ... arg0) {//TODO auto-generated method Stubmdownloadhttptool.ready (); return null;} @Overrideprotected void OnPostExecute (void result) {//TODO auto-generated method Stubsuper.onpostexecute (Result); FileSize = Mdownloadhttptool.getfilesize ();d ownloadedsize = Mdownloadhttptool.getcompeletesize (); LOG.W ("Tag", "Downloadedsize::" + downloadedsize); if (ondownloadlistener! = null) {Ondownloadlistener.downloadstart ( fileSize);} Mdownloadhttptool.start ();}}. Execute ();} public void Pause () {mdownloadhttptool.pause ();} public void Delete () {mdownloadhttptool.delete ();} public void Reset () {mdownloadhttptool.delete (); Start ();} public void Setondownloadlistener (Ondownloadlistener ondownloadlistener) {This.ondownloadlistener = Ondownloadlistener;} Download callback Interface Public InterfaCe ondownloadlistener {public void Downloadstart (int fileSize);p ublic void downloadprogress (int downloadedsize);// Record current all threads under sum public void Downloadend ();}}
In mainactivity
Package Com.example.test;import Android.os.bundle;import Android.os.environment;import Android.support.v4.app.fragmentactivity;import Android.util.log;import Android.view.view;import Android.view.view.onclicklistener;import Android.widget.button;import Android.widget.progressbar;import Android.widget.textview;import Com.example.test.downloadutil.ondownloadlistener;public class MainActivity extends fragmentactivity {private static final String TAG = MainActivity.class.getSimpleName ();p rivate ProgressBar Mprogressbar ;p rivate button start;private button pause;private button delete;private button reset;private TextView total;private int m Ax;private downloadutil mdownloadutil; @Overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate ( Savedinstancestate); Setcontentview (r.layout.activity_main); Mprogressbar = (ProgressBar) Findviewbyid ( R.ID.PROGRESSBAR1) Start = (Button) Findviewbyid (r.id.button_start);p ause = (button) Findviewbyid (r.id.button_pause) ;d elete = (Button) findviewByid (r.id.button_delete); reset = (Button) Findviewbyid (r.id.button_reset); total = (TextView) Findviewbyid ( R.id.textview_total); String urlstring = "Http://bbra.cn/Uploadfiles/imgs/20110303/fengjin/013.jpg"; String LocalPath = Environment.getexternalstoragedirectory (). GetAbsolutePath () + "/local"; mdownloadutil = new Downloadutil (2, LocalPath, "abc.jpg", Urlstring,this); Mdownloadutil.setondownloadlistener (new Ondownloadlistener () {@Overridepublic void Downloadstart (int fileSize) {//TODO auto-generated method STUBLOG.W (TAG, "fileSize::" + fileSize); max = Filesize;mprogressbar.setmax (fileSize);} @Overridepublic void downloadprogress (int downloadedsize) {//TODO auto-generated method STUBLOG.W (TAG, "Compelete::" + D ownloadedsize); mprogressbar.setprogress (downloadedsize); Total.settext ((int) downloadedsize * 100/max + "%");} @Overridepublic void Downloadend () {//TODO auto-generated method STUBLOG.W (TAG, "ENd");}); Start.setonclicklistener (New Onclicklistener () {@Overridepublic void OnClick (ViEW arg0) {//TODO auto-generated method Stubmdownloadutil.start ();}}); Pause.setonclicklistener (New Onclicklistener () {@Overridepublic void OnClick (View arg0) {//TODO auto-generated method Stubmdownloadutil.pause ();}}); Delete.setonclicklistener (New Onclicklistener () {@Overridepublic void OnClick (View arg0) {//TODO auto-generated method Stubmdownloadutil.delete ();}}); Reset.setonclicklistener (New Onclicklistener () {@Overridepublic void OnClick (View arg0) {//TODO auto-generated method Stubmdownloadutil.reset ();}});}}






Android Development-Multi-threaded download plus breakpoint continuation

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.