Android multi-Threaded download file principle domineering resolution introduction (end Version)-----Greendao database storage, breakpoint download

Source: Internet
Author: User
Tags create database

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.

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.