Android实现多线程断点续传

本文实例为大家分享了android实现多线程断点续传的具体代码,供大家参考,具体内容如下
多线程下载涉及到的知识点:
1、service的使用:我们在service中去下载文件;
2、thread的使用:service本身不支持耗时操作,所以我们要去开启线程;
3、sqlite的使用:使用数据库来存储每个线程下载的文件的进度,和文件的下载情况;
4、权限:涉及到文件的读写就要用到权限;
5、broadcastreceiver的使用:通过广播来更新下载进度;
6、线程池使用:使用线程池来管理线程,减少资源的浪费
7、httpurlconnection的使用:下载文件使用的
8、listview和baseadapter的使用:下载列表的显示
9、randomaccessfile使用
先解释一下我们要做什么:
1、我们现在有一个文件,然后要分成好几个线程去下载,那么我们需要将这个文件平分,然后分给各个线程去下载,而每个线程在下载的时候,你不一定啥时候点了暂停,那么就要记录我的下载进度,所以要用到数据库 。
2、你可能又会问,怎么去知道谁下载哪呢?我们的httpurlconnection可以通过他的setrequestproperty()方法设置下载范围,从哪开始到哪结束 。
3、同样下载解决了,那么写文件呢,怎么往文件里面写呢,那么就要用到randomaccessfile这个文件的特性了,从文件的任意位置开始写,是不是清晰了 。
4、 还有问题就是怎么更新界面,用我们的广播,告诉什么时候去更新界面 。
(实现的效果,是一个文件可以由多个线程下载,可以同时下载多个文件)
**这里需要注意:**不可以在获取长度后直接去下载文件,因为,我们获取文件长度的时候需要使用的请求码是200,如果我们想要分段去下载(也就是设置了connection.setrequestproperty(“range”,“bytes=”"之后就是分段下载了)那么使用到的请求码是206 。所以我们这里要将这两个请求分开来写,我就一开始将两个写到一起了,但是是不可以的会报错,更不要想着通过请求码来区分,这个就更错了
1、下面贴出***服务类***的代码:
这里的工作主要就是开启下载任务和停止下载任务,还有就是获取下载文件的长度,并创建本地文件并设置长度 。
public class downloadservice extends service {    public static final int status_start = 0;    public static final int status_stop = 1;    public static final string path = environment.getexternalstoragedirectory().getabsolutepath();    private fileinfo mfileinfo;    //统一管理downloadtask,有个文件下载就有个downloadtask,所以使用map去管理,主要控制暂停    private map<integer,object> downtaskmap = new hashmap<>();    private downloadtask downloadtask;    @override    public void oncreate() {        super.oncreate();    }    @override    public int onstartcommand(intent intent, int flags, int startid) {        if (intent != null) {            int status = intent.getintextra("status", 0);            if (status == status_start) {                //开始下载                mfileinfo = (fileinfo) intent.getserializableextra("fileinfo");                downloadtask.sexecutorservice.execute(new getfilelenght(mfileinfo, this));            } else {                //暂停下载                mfileinfo = (fileinfo) intent.getserializableextra("fileinfo");                log.e("---------->","mfileinfo:"+mfileinfo);                downloadtask = (downloadtask) downtaskmap.get(mfileinfo.getid());                if(downloadtask!=null){                    downloadtask.ispause = true;                }            }        }        return super.onstartcommand(intent, flags, startid);    }    @nullable    @override    public ibinder onbind(intent intent) {        return null;    }    /**     * 获得要下载的文件的长度,并创建本地文件     * 不能和下载的线程写在一起     */    class getfilelenght extends thread {        private fileinfo fileinfo;        private context context;        public getfilelenght(fileinfo fileinfo, context context) {            this.fileinfo = fileinfo;            this.context = context;        }        @override        public void run() {            super.run();            httpurlconnection conn = null;            randomaccessfile raf = null;            try {                url url = new url(fileinfo.geturl());                conn = (httpurlconnection) url.openconnection();                conn.setconnecttimeout(5000);                conn.setrequestmethod("get");                int length = -1;                if (conn.getresponsecode() == 200) {                    length = conn.getcontentlength();                    if (length > 0) {                        //创建本地文件                        file file = new file(path, fileinfo.getfile_name());                        raf = new randomaccessfile(file, "rwd");                        //设置本地文件的长度                        raf.setlength(length);                        fileinfo.setlength(length);                        //开始下载                        downloadtask =new downloadtask(downloadservice.this,fileinfo);                        downloadtask.down();                        downtaskmap.put(fileinfo.getid(),downloadtask);                    }                }            } catch (exception e) {                e.printstacktrace();            } finally {                conn.disconnect();                try {                    if (raf != null) {                        raf.close();                    }                } catch (ioexception e) {                    e.printstacktrace();                }            }        }    }}2、downloadtask的代码,也就是真正的核心的地方
这里的关系是一个fileinfo对应一个downloadtask,一个downloadtask对应着多个线程
package com.example.a_0102.mylearn.download;import android.content.context;import android.content.intent;import android.util.log;import java.io.file;import java.io.ioexception;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 java.util.concurrent.executorservice;import java.util.concurrent.executors;/** * 下载文件的内容 */public class downloadtask {    private context context;    private fileinfo fileinfo;    private int countforthread = 3;//线程的数量    private int mfinished;    private downloadtaskimpl downloadtask;    private list<threadinfo> threadinfos;    private list<downloadthread> downloadthreads;    public boolean ispause = false;    public static executorservice sexecutorservice = executors.newcachedthreadpool();//共用一个线程池    public downloadtask(context context,fileinfo fileinfo) {        this.fileinfo = fileinfo;        this.context = context;        downloadtask = new downloadtaskimpl(context);    }    public void down(){        threadinfos = downloadtask.getthreadinfos(fileinfo.geturl());        if(threadinfos.size() == 0){            mfinished = 0;            //计算每个线程应下载的长度            int every_length = fileinfo.getlength()/countforthread;            for(int i = 0;i<countforthread;i++){                threadinfo threadinfo = new threadinfo();                threadinfo.setstart_flag(i*every_length);                threadinfo.setend_flag((i+1)*every_length-1);                threadinfo.setfinished(0);                threadinfo.seturl(fileinfo.geturl());                threadinfo.setthread_id(i);                //可能不能平分,最后一个线程的长度为剩余的所有                if(i == countforthread-1){                    threadinfo.setend_flag(fileinfo.getlength());                }                downloadtask.insertthreadinfo(threadinfo);                threadinfos.add(threadinfo);            }        }else {            //该文件一共下载了多少了            mfinished = fileinfo.getfinished();        }        downloadthreads = new arraylist<>();        downloadthread downloadthread = null;        for(int i = 0;i<threadinfos.size();i++){            downloadthread = new downloadthread(threadinfos.get(i));//            downloadthread.start();            downloadtask.sexecutorservice.execute(downloadthread);//执行线程,相当于开启个线程使用这个就不需要使用.start方法            downloadthreads.add(downloadthread);        }    }    //真正开始下载文件的线程    class downloadthread extends thread{        private threadinfo threadinfo;        private boolean isfinished;//该线程是否结束        public downloadthread(threadinfo threadinfo) {            this.threadinfo = threadinfo;            log.e("------------->","threadinfo:"+threadinfo);        }        @override        public void run() {            super.run();            httpurlconnection connection = null;            randomaccessfile accessfile = null;            inputstream inputstream = null;            intent intent = new intent();            intent.setaction("update_progressbar");            try {                url url = new url(threadinfo.geturl());                connection = (httpurlconnection) url.openconnection();                connection.setrequestmethod("get");                connection.setconnecttimeout(5000);                //下载开始的范围是,这个线程的开始下载的地方+已经下载的进度                long start = threadinfo.getstart_flag()+threadinfo.getfinished();                //设置下载的范围                connection.setrequestproperty("range","bytes="+start+"-"+threadinfo.getend_flag());                file file = new file(downloadservice.path,fileinfo.getfile_name());                accessfile = new randomaccessfile(file,"rwd");                //设置文件写入位置                accessfile.seek(start);                int len = -1;                byte[] bytes = new byte[1024];                if(connection.getresponsecode() == 206){                    inputstream = connection.getinputstream();                    long time = system.currenttimemillis();                    while ((len = inputstream.read(bytes))!=-1){                        accessfile.write(bytes,0,len);                        //文件整体的下载进度                        mfinished+=len;                        threadinfo.setfinished(threadinfo.getfinished()+len);                        //每1秒钟发送一个广播更新界面                        if(system.currenttimemillis()-time>1000){                            time = system.currenttimemillis();                            //以便区分下载的是那个文件                            intent.putextra("id",fileinfo.getid());                            intent.putextra("length",fileinfo.getlength());                            intent.putextra("finished",mfinished);                            context.sendbroadcast(intent);                        }                        //暂停更新数据库                        if(ispause){                            downloadtask.updatethreadinfo(threadinfo,threadinfo.getthread_id(),threadinfo.geturl());                            return;                        }                    }                    log.e("------------>","线程结束:"+threadinfo.tostring());                    isfinished = true;                    downloadtask.updatethreadinfo(threadinfo,threadinfo.getthread_id(),threadinfo.geturl());                    checkallthreadfinish();                }            } catch (exception e) {                e.printstacktrace();            }finally {                connection.disconnect();                if(inputstream!=null){                    try {                        inputstream.close();                        accessfile.close();                    } catch (ioexception e) {                        e.printstacktrace();                    }                }            }        }        //所有的线程下载完成        private synchronized void checkallthreadfinish(){            boolean finishall = true;            for(downloadthread downloadthread:downloadthreads){                if(!downloadthread.isfinished){                    finishall = false;                    return;                }            }            if(finishall){                downloadtask.deletethreadinfo(fileinfo.geturl());                //有些时候可能刚好下完,但是那1秒的时候没有取到所以进度可能停在97%,所以这样处理保证视觉的效果,可以直接将mfinished替换为fileinfo.getlength() 。                intent intent = new intent();                intent.setaction("update_progressbar");                intent.putextra("id",fileinfo.getid());                intent.putextra("length",fileinfo.getlength());                intent.putextra("finished",mfinished);                context.sendbroadcast(intent);            }        }    }}3、界面的代码
上面罗列知识点的时候,说到了权限,如果手机系统是6.0 以上的要获取权限即请求用户允许的那种,否则会出现android.system.errnoexception: open failed: eacces (permission denied)异常,下面代码中涉及权限的就是模拟一下,具体逻辑没有严格的去实现,大家看的时候需要注意 。。
package com.example.a_0102.mylearn.download;import android.content.broadcastreceiver;import android.content.context;import android.content.intent;import android.content.intentfilter;import android.support.v7.app.appcompatactivity;import android.os.bundle;import android.util.log;import android.view.layoutinflater;import android.view.view;import android.view.viewgroup;import android.widget.baseadapter;import android.widget.button;import android.widget.listview;import android.widget.progressbar;import com.example.a_0102.mylearn.r;import java.util.arraylist;import java.util.list;/** * 断点续传 * 一个文件可以分成几部分,使用不同的线程进行下载,使用数据库存储每个线程的下载进度 */public class downloadactivity extends appcompatactivity {    private listview mlistview;    private list<fileinfo> fileinfolist;    private listviewadapter adapter;    private updateuireceiver mupdateuireceiver;    private downloadtaskimpl downloadtask;    private button mbtndel;    private intent intent;    @override    protected void oncreate(bundle savedinstancestate) {        super.oncreate(savedinstancestate);        setcontentview(r.layout.activity_down_load);        //申请权限        if (contextcompat.checkselfpermission(downloadactivity.this, manifest.permission.write_external_storage) != packagemanager.permission_granted) {            //没有权限            log.e("------------->", "没有权限");            activitycompat.requestpermissions(downloadactivity.this, new string[]{manifest.permission.write_external_storage}, 0);        } else {            log.e("------------->", "已经有权限");        }        mbtndel = findviewbyid(r.id.btn_del);        downloadtask = new downloadtaskimpl(this);        //从数据库获取要下载的文件        fileinfolist = new arraylist<>();        fileinfolist = downloadtask.getfileinfo();        //这里是用来模拟,具体请按照需求来写        if (fileinfolist.size() == 0) {            fileinfo fileinfo1 = new fileinfo(0, "http://oslw24znh.bkt.clouddn.com/android2017_07_05.apk", "xiaobang.apk", 0, 0, 0);            fileinfo fileinfo2 = new fileinfo(1, "http://ofmudsqae.bkt.clouddn.com/%e5%91%a8%e5%86%ac%e9%9b%a8%20-%20%e4%b8%8d%e5%ae%8c%e7%be%8e%e5%a5%b3%e5%ad%a9.mp3", "buwanmei.mp3", 0, 0, 0);            fileinfolist.add(fileinfo1);            fileinfolist.add(fileinfo2);        }        mlistview = findviewbyid(r.id.listview);        adapter = new listviewadapter();        mlistview.setadapter(adapter);        //为了测试写的,可忽略        mbtndel.setonclicklistener(new view.onclicklistener() {            @override            public void onclick(view v) {                log.e("------------>","dddsize:"+downloadtask.getfileinfo().size());                downloadtask.deletefileinfo();                log.e("------------>","size:"+downloadtask.getfileinfo().size());                downloadtask.deletethreadinfo();            }        });    }    //申请权限的回调    @override    public void onrequestpermissionsresult(int requestcode, @nonnull string[] permissions, @nonnull int[] grantresults) {        super.onrequestpermissionsresult(requestcode, permissions, grantresults);        log.e("------------->", "requestcode:" + requestcode + "," + permissions[0]);        if (requestcode == 0) {            if (grantresults.length > 0 && grantresults[0] == packagemanager.permission_granted){                log.e("------------->", "授权被允许" );            }else {                log.e("------------->", "授权没有被允许" );            }        }    }    @override    protected void onresume() {        super.onresume();        // 1. 实例化broadcastreceiver子类 &  intentfilter        mupdateuireceiver = new updateuireceiver();        intentfilter intentfilter = new intentfilter();        // 2. 设置接收广播的类型        intentfilter.addaction("update_progressbar");        // 3. 动态注册:调用context的registerreceiver()方法        registerreceiver(mupdateuireceiver, intentfilter);    }    // 注册广播后,要在相应位置记得销毁广播// 即在onpause() 中unregisterreceiver(mbroadcastreceiver)// 当此activity实例化时,会动态将mybroadcastreceiver注册到系统中// 当此activity销毁时,动态注册的mybroadcastreceiver将不再接收到相应的广播 。    @override    protected void onpause() {        super.onpause();        //销毁在onresume()方法中的广播        unregisterreceiver(mupdateuireceiver);    }    @override    protected void ondestroy() {        super.ondestroy();        if (intent == null) {            return;        }        stopservice(intent);    }    private class listviewadapter extends baseadapter {        @override        public int getcount() {            return fileinfolist.size();        }        @override        public object getitem(int position) {            return fileinfolist.get(position);        }        @override        public long getitemid(int position) {            return position;        }        @override        public view getview(final int position, view convertview, viewgroup parent) {            viewholder viewholder = null;            if (convertview == null) {                convertview = layoutinflater.from(downloadactivity.this).inflate(r.layout.layout_down_item, parent, false);                viewholder = new viewholder();                viewholder.mprogress = convertview.findviewbyid(r.id.progress);                viewholder.mbtndown = convertview.findviewbyid(r.id.btn_down);                viewholder.mbtnstop = convertview.findviewbyid(r.id.btn_stop);                convertview.settag(viewholder);                //不用更新的尽量写在这里,防止每次都调用,进度设置为100                viewholder.mprogress.setmax(100);                viewholder.mbtndown.setonclicklistener(new view.onclicklistener() {                    @override                    public void onclick(view v) {                        intent = new intent(downloadactivity.this, downloadservice.class);                        intent.putextra("status", downloadservice.status_start);                        intent.putextra("fileinfo", fileinfolist.get(position));                        startservice(intent);                        if (!downloadtask.isexitfileinfo(fileinfolist.get(position).getid())) {                            downloadtask.insertfileinfo(fileinfolist.get(position));                        }                    }                });                viewholder.mbtnstop.setonclicklistener(new view.onclicklistener() {                    @override                    public void onclick(view v) {                        intent = new intent(downloadactivity.this, downloadservice.class);                        intent.putextra("status", downloadservice.status_stop);                        intent.putextra("fileinfo", fileinfolist.get(position));                        startservice(intent);                    }                });            } else {                viewholder = (viewholder) convertview.gettag();            }            fileinfo fileinfo = fileinfolist.get(position);            viewholder.mprogress.setprogress(fileinfo.getprogress());            return convertview;        }        class viewholder {            private progressbar mprogress;            private button mbtndown;            private button mbtnstop;        }    }    /**     * 用于更新ui的广播     * 使用静态注册的广播,广播的类如果是内部类,那么,该类必须为static修饰的类,否则has no zero argument constructor 这个异常     * https://blog.csdn.net/zhongjianblackberry/article/details/56670084     * 或者用动态注册广播     */    public class updateuireceiver extends broadcastreceiver {        @override        public void onreceive(context context, intent intent) {            if (intent.getaction().equals("update_progressbar")) {                int id = intent.getintextra("id", 0);                int finished = intent.getintextra("finished", 0);                int length = intent.getintextra("length", 0);                if (length == 0 || length < 0) {                    return;                }                int progress = finished * 100 / length;                fileinfo fileinfo = fileinfolist.get(id);                fileinfo.setfinished(finished);                fileinfo.setlength(length);                fileinfo.setprogress(progress);                adapter.notifydatasetchanged();                downloadtask.updatefileinfo(fileinfo, id);            }        }    }}4、接下来是文件类和线程类的代码
public class fileinfo implements serializable {    private int id;    private string url;//文件的url    private string file_name;//文件名称    private int progress;//当前进度(显示在进度条上的)    private int finished;//已下载完的(实际下载的大小)    private int length;//文件的大小    public fileinfo() {    }    public fileinfo(int id, string url, string file_name, int progress, int finished, int length) {        this.id = id;        this.url = url;        this.file_name = file_name;        this.progress = progress;        this.finished = finished;        this.length = length;    }    public int getid() {        return id;    }    public void setid(int id) {        this.id = id;    }    public string geturl() {        return url;    }    public void seturl(string url) {        this.url = url;    }    public string getfile_name() {        return file_name;    }    public void setfile_name(string file_name) {        this.file_name = file_name;    }    public int getprogress() {        return progress;    }    public void setprogress(int progress) {        this.progress = progress;    }    public int getlength() {        return length;    }    public void setlength(int length) {        this.length = length;    }    public int getfinished() {        return finished;    }    public void setfinished(int finished) {        this.finished = finished;    }    @override    public string tostring() {        return "fileinfo{" +                "id=" + id +                ", url='" + url + '\'' +                ", file_name='" + file_name + '\'' +                ", progress=" + progress +                ", finished=" + finished +                ", length=" + length +                '}';    }}public class threadinfo implements serializable {    private int id;//主键自增    private int thread_id;//如果没有id,唯一的标识,多线程的时候就不知道更新哪个了    private string url;    private long start_flag;    private long end_flag;    private long finished;//该线程的下载进度    public threadinfo() {    }    public threadinfo(int thread_id, string url, long start_flag, long end_flag, long finished) {        this.thread_id = thread_id;        this.url = url;        this.start_flag = start_flag;        this.end_flag = end_flag;        this.finished = finished;    }    public int getid() {        return id;    }    public void setid(int id) {        this.id = id;    }    public int getthread_id() {        return thread_id;    }    public void setthread_id(int thread_id) {        this.thread_id = thread_id;    }    public string geturl() {        return url;    }    public void seturl(string url) {        this.url = url;    }    public long getstart_flag() {        return start_flag;    }    public void setstart_flag(long start_flag) {        this.start_flag = start_flag;    }    public long getend_flag() {        return end_flag;    }    public void setend_flag(long end_flag) {        this.end_flag = end_flag;    }    public long getfinished() {        return finished;    }    public void setfinished(long finished) {        this.finished = finished;    }    @override    public string tostring() {        return "threadinfo{" +                "id=" + id +                ", thread_id=" + thread_id +                ", url='" + url + '\'' +                ", start_flag=" + start_flag +                ", end_flag=" + end_flag +                ", finished=" + finished +                '}';    }}5、数据库的代码
这里要用单例模式,否则会报错
import android.content.context;import android.database.sqlite.sqlitedatabase;import android.database.sqlite.sqliteopenhelper;/** * 要用单例的,否则会出现cannot perform this operation because the connection pool has been closed */public class dbhalper extends sqliteopenhelper {    private static final string db_name = "downloadfile";    private static final int db_version = 1;    private static final string create_thread_info = "create table thread_info (id integer primary key autoincrement,thread_id int,url text ,start_flag int,end_flag int,finished int);";    private static final string create_file_info = "create table file_info (id integer primary key,url text ,file_name text,length int,progress int,finished int);";    private static dbhalper dbhalper;    public static dbhalper getdbhalper(context context){        if(dbhalper == null){            dbhalper = new dbhalper(context);        }        return dbhalper;    }    private dbhalper(context context) {        super(context, db_name, null, db_version);    }    @override    public void oncreate(sqlitedatabase db) {        db.execsql(create_thread_info);        db.execsql(create_file_info);    }    @override    public void onupgrade(sqlitedatabase db, int oldversion, int newversion) {    }}public interface idownloadtask {    /**     * 插入线程信息     *     * @param threadinfo     */    void insertthreadinfo(threadinfo threadinfo);    /**     * 更新线程信息     *     * @param threadinfo     * @param id     */    void updatethreadinfo(threadinfo threadinfo, int id, string url);    /**     * 删除下载完成的线程记录     *     * @param url     */    void deletethreadinfo(string url);    /**     * 获取所有线程信息     *     * @param url     * @return     */    list<threadinfo> getthreadinfos(string url);    /**     * 获取所有线程信息     *     * @return     */    list<threadinfo> getthreadinfos();    /**     * 插入文件信息     *     * @param fileinfo     */    void insertfileinfo(fileinfo fileinfo);    /**     * 修改文件的信息     *     * @param fileinfo     * @param id     */    void updatefileinfo(fileinfo fileinfo, int id);    /**     * 该文件信息是否存在     *     * @param id     * @return     */    boolean isexitfileinfo(int id);    /**     * 查询文件信息     *     * @return     */    list<fileinfo> getfileinfo();    /**     * 删除文件信息     */    void deletefileinfo();    /**     * 删除文件下载的线程信息     */    void deletethreadinfo();}接口类的实现,注意同步,否则多个线程一起操作一个方法会出现“惊喜“
【Android实现多线程断点续传】import android.content.context;import android.database.cursor;import android.database.sqlite.sqlitedatabase;import java.util.arraylist;import java.util.list;/** * 增、删、改方法要保证线程安全,同一时刻只能有一个线程访问 */public class downloadtaskimpl implements idownloadtask {    private dbhalper dbhalper;    private sqlitedatabase db;    public downloadtaskimpl(context context) {        dbhalper = dbhalper.getdbhalper(context);    }    @override    public synchronized void insertthreadinfo(threadinfo threadinfo) {        sqlitedatabase db = dbhalper.getwritabledatabase();        db.execsql("insert into thread_info (thread_id,url,start_flag,end_flag,finished) values (?,?,?,?,?);",                new object[]{threadinfo.getthread_id(),threadinfo.geturl(),threadinfo.getstart_flag(),                        threadinfo.getend_flag(),threadinfo.getfinished()});        db.close();    }    @override    public synchronized void updatethreadinfo(threadinfo threadinfo, int thread_id,string url) {        sqlitedatabase db = dbhalper.getwritabledatabase();        db.execsql("update thread_info set thread_id=?, url=?,start_flag=?,end_flag=?,finished=?  where thread_id = ? and url = ?;",                new object[]{threadinfo.getthread_id(),threadinfo.geturl(), threadinfo.getstart_flag(),                        threadinfo.getend_flag(),threadinfo.getfinished(),thread_id,url});        db.close();    }    @override    public synchronized void deletethreadinfo(string url) {        sqlitedatabase db = dbhalper.getwritabledatabase();        db.execsql("delete from thread_info where url=?;",new string[]{url});        db.close();    }    @override    public list<threadinfo> getthreadinfos(string url) {            list<threadinfo> threadinfos = new arraylist<>();            sqlitedatabase db = dbhalper.getreadabledatabase();            cursor cursor = db.rawquery("select * from thread_info where url=?;",new string[]{url});            while (cursor.movetonext()){                threadinfo threadinfo = new threadinfo();                threadinfo.setthread_id(cursor.getint(cursor.getcolumnindex("thread_id")));                threadinfo.seturl(cursor.getstring(cursor.getcolumnindex("url")));                threadinfo.setstart_flag(cursor.getint(cursor.getcolumnindex("start_flag")));                threadinfo.setend_flag(cursor.getint(cursor.getcolumnindex("end_flag")));                threadinfo.setfinished(cursor.getint(cursor.getcolumnindex("finished")));                threadinfos.add(threadinfo);            }            cursor.close();            db.close();            return threadinfos;        }    @override    public list<threadinfo> getthreadinfos() {        list<threadinfo> threadinfos = new arraylist<>();        sqlitedatabase db = dbhalper.getreadabledatabase();        cursor cursor = db.rawquery("select * from thread_info;",new string[]{});        while (cursor.movetonext()){            threadinfo threadinfo = new threadinfo();            threadinfo.setthread_id(cursor.getint(cursor.getcolumnindex("thread_id")));            threadinfo.seturl(cursor.getstring(cursor.getcolumnindex("url")));            threadinfo.setstart_flag(cursor.getint(cursor.getcolumnindex("start_flag")));            threadinfo.setend_flag(cursor.getint(cursor.getcolumnindex("end_flag")));            threadinfo.setfinished(cursor.getint(cursor.getcolumnindex("finished")));            threadinfos.add(threadinfo);        }        cursor.close();        db.close();        return threadinfos;    }    @override    public synchronized void insertfileinfo(fileinfo fileinfo) {        sqlitedatabase db = dbhalper.getwritabledatabase();        db.execsql("replace into file_info (id,url,file_name,length,progress,finished) values (?,?,?,?,?,?);",                new object[]{fileinfo.getid(),fileinfo.geturl(),fileinfo.getfile_name(),fileinfo.getlength(),                        fileinfo.getprogress(),fileinfo.getfinished()});        db.close();    }    @override    public synchronized void updatefileinfo(fileinfo fileinfo, int id) {        sqlitedatabase db = dbhalper.getwritabledatabase();        db.execsql("update file_info set id=?, url=?,file_name=?,length=?,progress=?,finished=?  where id = ?;",                new object[]{fileinfo.getid(),fileinfo.geturl(), fileinfo.getfile_name(),fileinfo.getlength(),                        fileinfo.getprogress(),fileinfo.getfinished(),id});        db.close();    }    @override    public boolean isexitfileinfo(int id) {        sqlitedatabase db = dbhalper.getreadabledatabase();        boolean isexit = false;        cursor cursor = db.rawquery("select * from file_info where id=?;",new string[]{id+""});        while (cursor.movetonext()){            isexit = true;        }        cursor.close();        db.close();        return isexit;    }    @override    public list<fileinfo> getfileinfo() {        list<fileinfo> fileinfos = new arraylist<>();        sqlitedatabase db = dbhalper.getreadabledatabase();        cursor cursor = db.rawquery("select * from file_info;",new string[]{});        while (cursor.movetonext()){            fileinfo fileinfo = new fileinfo();            fileinfo.setid(cursor.getint(cursor.getcolumnindex("id")));            fileinfo.seturl(cursor.getstring(cursor.getcolumnindex("url")));            fileinfo.setfile_name(cursor.getstring(cursor.getcolumnindex("file_name")));            fileinfo.setlength(cursor.getint(cursor.getcolumnindex("length")));            fileinfo.setprogress(cursor.getint(cursor.getcolumnindex("progress")));            fileinfo.setfinished(cursor.getint(cursor.getcolumnindex("finished")));            fileinfos.add(fileinfo);        }        cursor.close();        db.close();        return fileinfos;    }    @override    public synchronized void deletefileinfo() {        sqlitedatabase db = dbhalper.getwritabledatabase();        db.execsql("delete from file_info;",new string[]{});        db.close();    }    @override    public void deletethreadinfo() {        sqlitedatabase db = dbhalper.getwritabledatabase();        db.execsql("delete from thread_info;",new string[]{});        db.close();    }}提示:可以直接使用filedownloader一个开源的下载大文件的框架,使用就自行百度吧
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持www.887551.com 。
-- 展开阅读全文 --

    推荐阅读