This article mainly describes, if paused, or network segment, and then there is a recovery, and then continue to download.
First, we'll add the database Greendao
Step 1: First create a Java modle in the project. As shown in figure
Step 2: Create the Dbgenerate file,
public class Dbgenerate {public
static void Main (String args[]) {
//version number \ Package Name
Schema schema = new schema (1, " Com.imooc.db ");
Entity Entity = schema.addentity ("downloadentity");
Sets the key name
entity.addlongproperty ("start_position");
Entity.addlongproperty ("End_position");
Entity.addlongproperty ("Progress_position");
Entity.addstringproperty ("Download_url");
Entity.addintproperty ("thread_id");
Set Primary key
Entity.addidproperty (). AutoIncrement ();
try {
new Daogenerator (). Generateall (Schema, "Dbgenerate/src-gen");
} catch (Exception e) {
E.printstacktrace ();}}
Step 3: Then create the "Src-gen" Directory empty folder
Step 4: Recompile the project, there will be 4 files inside the Src-gen, copy to the project directly use it.
Step 5: Add in the Gradle of the project you are using to complete
Compile ' de.greenrobot:greendao-generator:2.1.0 '
Compile ' de.greenrobot:greendao:2.1.0 '
after the data has been added, let's look at how to use it in this download case.
* * First create Downloadhelper action class public class Downloadhelper {
private Daomaster Mmaster;
Private Daosession msession;
Private Downloadentitydao Mdao;
private static Downloadhelper Shelper = new Downloadhelper ();
public static Downloadhelper getinstance () {return shelper;}
Private Downloadhelper () {}/** * Initialize, CREATE DATABASE * @param context/public void init (context context) {//database name
Sqlitedatabase db = new Daomaster.devopenhelper (context, "download.db", null). Getwritabledatabase ();
Mmaster = new Daomaster (db);
Msession = Mmaster.newsession ();
Mdao = Msession.getdownloadentitydao ();
/** * Save Data * @param entity */public void Insert (downloadentity entity) {Mdao.insertorreplace (entity);} /** * Get all data * @param URL * @return/public list<downloadentity> getAll (String URL) {return mdao.querybui Lder (). where (DownloadEntityDao.Properties.Download_url.eq (URL)). ORDERASC (DownloadEntityDao.Properties.Thread_
ID). list (); }
}1, first in Downloadmanager in the download Download method, first read the database, there is no data, if there is data in the previous logic to go, normal download, if not, on the query database data, and then download. Then update the progress bar *
/** * To determine how long each thread downloads data, and multithreading download/public void DownLoad (final String URL, final downloadcallback callBack) {
Before downloading the database has not previously downloaded Mcache = Downloadhelper.getinstance (). GetAll (URL); if (Mcache = null | | mcache.size () = 0) {//If no previous download, no cache normal walk httpmanager.getinstance (). asyncrequ
EST (url, new Callback () {@Override public void onfailure (call call, IOException e) { @Override public void Onresponse (call call, Response Response) throws Ioex ception {if (response = = NULL && callBack!= null) {Callback.fail (Htt
Pmanager.network_error_code, "network Problem");
Return
Length = Response.body (). ContentLength (); if (length = = 1) {//Get the total length of the file Callback.fail (httpmanager.content_leNgth_error_code, "contenLength-1");
Return
} processdownload (URL, length, callBack, Mcache);
}
}); }else {///previous download logic for (int i = 0; i < mcache.size (); i++) {//Remove the download length per thread storage,
New Download Downloadentity entity = Mcache.get (i);
Long startsize = entity.getstart_position () + entity.getprogress_position ();
Long endsize = Entity.getend_position ();
Sthreadpool.execute (New Downloadrunnable (startsize, endsize, URL, CallBack, entity)); Gets the total length of the file, and the progress download uses the IF (i = = Mcache.size ()-1) {length = Mcache.get (i). getend_position
() + 1; {}}//TODO: Update download Progress Slocalprogresspool.execute Runnable () {@Overri
De public void run () {while (true) { try {//Every 500 update thread.sleep (500);
Take to the downloaded file: Fliestoragemanager.getinstance (). Getfilebyname (URL);
Long fileSize = File.length ();
Calculates the percentage of downloads int progress = (int) (fileSize * 100/length);
Callback.progress (progress);
Download the exit thread, cycle if (progress >=) {callback.progress (progress);
Return
} catch (Interruptedexception e) {e.printstacktrace ();
}
}
}
}); }
2, and then take a look at our download save operation:
/** * Download * @param length of the download file to save the data/private void Processdownload (String url, long length, do Wnloadcallback callback,list<downloadentity> Cache) {if cache = null | | cache.size () = 0) {m
Cache = new arraylist<> ();
//Calculate the size of each thread download long threaddownloadsize = Length/max_thread; Allocate each thread download for (int i = 0; i < Max_thread i++) {//Calculate how many downloads per thread, such as length 100 2 threads 0-49 50-99, below are
Calculation of the algorithm long startsize = i * threaddownloadsize;
Long endsize = 0;
if (endsize = = max_thread-1) {endsize = length-1;
else {endsize = (i + 1) * THREADDOWNLOADSIZE-1;
//Create entity, save to database downloadentity entity = new downloadentity ();
Entity.setdownload_url (URL);
Entity.setend_position (endsize);
Entity.setstart_position (startsize); Entity.setthread_id (i + 1);
Execute Download sthreadpool.execute (new downloadrunnable (startsize, endsize, URL, CallBack, entity)); }
}
look at the operation inside the thread:
public class Downloadrunnable implements runnable{/** Specifies the download start location/private long mstart;
/** Specifies the download end position/private long mEnd;
/** requests url*/private String Murl;
/** Result Callback * * Private downloadcallback mcallback;
/** need to save the data of the Entity information class * * Private downloadentity mentity;
Public downloadrunnable (Long Mstart, long mEnd, String Murl, Downloadcallback mcallback, downloadentity entity) {
This.mstart = Mstart;
This.mend = mEnd;
This.murl = Murl;
This.mcallback = Mcallback;
This.mentity = entity; @Override the results returned after the public void run () {//download is complete response response response = Httpmanager.getinstanc
E (). Syncrequestbyrange (Murl, Mstart, mEnd);
if (response = = NULL && mcallback!= null) {Mcallback.fail (Httpmanager.network_error_code, "network Problem");
Return
//Get local download-stored files file = Fliestoragemanager.getinstance (). Getfilebyname (Murl);The use is, if I break the net or pause, kill the app, get back in, take progress based on this field long finshprogress = mentity.getprogress_position () = null?
0:mentity.getprogress_position ();
Record the progress of the thread download long progress = 0; Multiple threads write data to the location specified by the file (because it is a multithreaded download, multiple threads will certainly read and write to a file) try {//Parameter 1: Specify the operation's file parameter 2: Readable writable to modify Ra
Ndomaccessfile randomaccessfile = new Randomaccessfile (file, "RWD");
Specifies an offset, the starting position of the download Randomaccessfile.seek (mstart);
byte[] buffer = new byte[1024];
int len = 0;
InputStream InputStream = Response.body (). ByteStream (); Reads the returned data and writes to the local file while (len = inputstream.read (buffer, 0, buffer.length))!=-1) {Randoma
Ccessfile.write (buffer, 0, Len);
Update the progress of the database progress + = Len;
Mentity.setprogress_position (progress); }//Database access data + Kill app come in after record = = never quit application Progress mentity.setprogress_position (MEntity.getprogress_position () + finshprogress);
Randomaccessfile.close ();
Successful download mcallback.success (file);
catch (FileNotFoundException e) {e.printstacktrace ();
catch (IOException e) {e.printstacktrace ();
}finally {///downloaded data is saved to the database Downloadhelper.getinstance (). Insert (mentity); }
}
}
then initialize the database in the applaction of the project
public class Myapplacation extends application {
@Override public
void OnCreate () {
super.oncreate ();
Fliestoragemanager.getinstance (). Init (this);
Initialize database
downloadhelper.getinstance (). Init (this);
}
download apk case:
private void Multipledownfileimage () {
Downloadmanager.getinstance (). DownLoad ("Http://szimg.mukewang.com/5763765d0001352105400300-360-202.jpg", new Downloadcallback () {
Downloadmanager.getinstance (). DownLoad ("http://shouji.360tpcdn.com/160901/84c090897cbf0158b498da0f42f73308/ com.icoolme.android.weather_2016090200.apk ", new Downloadcallback () {
@Override
public void Success (final file file) {
The current successful callback two times, through the cout identification of temporary solution
if (cout < 1) {
cout++;
Return
}
LOG.E ("File", "File success:" + File.getabsolutepath ());
LOG.E ("File", "File:" + file.length ());
}
@Override public
void fail (int errorcode, String errormessage) {
log.e ("File", "Shibai");
}
@Override Public
void Progress (int progress) {
log.e ("File", "Progress:" + progress);
Mprogress.setprogress (progress);
}
);
OK, multithreading download apk case, said finished. After reading these 4 articles, I believe they can be learned.