一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Android - Android實現斷點下載的方法

Android實現斷點下載的方法

2021-06-21 17:48Android開發網 Android

這篇文章主要為大家詳細介紹了Android實現斷點下載的方法,感興趣的小伙伴們可以參考一下

最近做的項目中需要實現斷點下載,即用戶一次下載可以分多次進行,下載過程可以中斷,在目前大多數的帶離線緩存的軟件都是需要實現這一功能。本文闡述了通過sqlite3簡單實現了一個具有斷點下載功能的demo。言歸正傳,開始正文。

設計

數據庫表存儲元數據
dbhelper.java
用于業務存儲的dao
dao.java
抽象下載信息的bean
loadinfo.java
呈現下載信息view
mainactivity.java
存儲下載信息bean
downloadinfo.java
封裝好的下載類
downloader.java

代碼結構

Android實現斷點下載的方法

具體實現

下載信息類:downloadinfo.java

這里的代碼很簡單,就是一個用來保存下載信息的類,很簡單,沒啥好說的,具體看注釋

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package entity;
public class downloadinfo {
 
  private int threadid;//線程id
 
  private int startpos;//下載起始位置
 
  private int endpos;//下載結束位置
 
  private int completesize;//下載完成量
 
  private string url;//資源url
 
  public downloadinfo(int tid,int sp, int ep,int csize,string address){
    threadid=tid;
    startpos=sp;
    endpos=ep;
    completesize = csize;
    url=address;
  }
 
  /**
   * @return the threadid
   */
  public int getthreadid() {
    return threadid;
  }
 
  /**
   * @param threadid the threadid to set
   */
  public void setthreadid(int threadid) {
    this.threadid = threadid;
  }
 
  /**
   * @return the startpos
   */
  public int getstartpos() {
    return startpos;
  }
 
  /**
   * @param startpos the startpos to set
   */
  public void setstartpos(int startpos) {
    this.startpos = startpos;
  }
 
  /**
   * @return the endpos
   */
  public int getendpos() {
    return endpos;
  }
 
  /**
   * @param endpos the endpos to set
   */
  public void setendpos(int endpos) {
    this.endpos = endpos;
  }
 
  /**
   * @return the completesize
   */
  public int getcompletesize() {
    return completesize;
  }
 
  /**
   * @param completesize the completesize to set
   */
  public void setcompletesize(int completesize) {
    this.completesize = completesize;
  }
 
  /**
   * @return the url
   */
  public string geturl() {
    return url;
  }
 
  /**
   * @param url the url to set
   */
  public void seturl(string url) {
    this.url = url;
  }
 
  @override
  public string tostring() {
    // todo auto-generated method stub
    return "threadid:"+threadid+",startpos:"+startpos+",endpos:"+endpos+",completesize:"+completesize+",url:"+url;
  }
}

數據庫 dbhelper.java

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package db;
 
import android.content.context;
import android.database.sqlite.sqlitedatabase;
import android.database.sqlite.sqliteopenhelper;
 
public class dbhelper extends sqliteopenhelper {
 
  string sql ="create table download_info (id integer primary key autoincrement,"
      + "thread_id integer,"
      + "start_pos integer,"
      + "end_pos integer,"
      + "complete_size integer,"
      + "url char)";
 
  public dbhelper(context context) {
    // todo auto-generated constructor stub
    super(context, "download.db", null, 1);
  }
 
  @override
  public void oncreate(sqlitedatabase db) {
    // todo auto-generated method stub
    db.execsql(sql);
  }
 
  @override
  public void onupgrade(sqlitedatabase db, int oldversion, int newversion) {
    // todo auto-generated method stub
 
  }
 
}

數據庫業務管理類 dao.java

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package db;
 
import java.util.arraylist;
import java.util.list;
 
import android.content.context;
import android.database.cursor;
import android.database.sqlite.sqlitedatabase;
import entity.downloadinfo;
 
public class dao {
 
  private dbhelper dbhelper;
 
  public dao(context context){
    dbhelper = new dbhelper(context);
  }
 
  public boolean isnewtask(string url){
    sqlitedatabase db = dbhelper.getreadabledatabase();
    string sql = "select count(*) from download_info where url=?";
    cursor cursor = db.rawquery(sql, new string[]{url});
    cursor.movetofirst();
    int count = cursor.getint(0);
    cursor.close();
    return count == 0;
  }
 
  public void saveinfo(list<downloadinfo> infos){
    sqlitedatabase db = dbhelper.getwritabledatabase();
    string sql = "insert into download_info(thread_id,start_pos,end_pos,complete_size,url) values(?,?,?,?,?)";
    object[] bindargs= null;
    for(downloadinfo info:infos){
      bindargs=new object[]{info.getthreadid(),info.getstartpos(),info.getendpos(),info.getcompletesize(),info.geturl()};
      db.execsql(sql, bindargs);
    }
 
  }
  public list<downloadinfo> getinfo(string url){
    sqlitedatabase db = dbhelper.getreadabledatabase();
    list<downloadinfo> infos = new arraylist<downloadinfo>();
    string sql ="select thread_id,start_pos,end_pos,complete_size,url from download_info where url=?";
    cursor cursor=db.rawquery(sql, new string[]{url});
    while(cursor.movetonext()){
      downloadinfo info = new downloadinfo(cursor.getint(0), cursor.getint(1), cursor.getint(2), cursor.getint(3),cursor.getstring(4));
      infos.add(info);
    }
    cursor.close();
    return infos;
 
  }
 
  public void deleteinfo(string url){
    sqlitedatabase db = dbhelper.getwritabledatabase();
    db.delete("download_info", "url=?", new string[]{url});
    db.close();
  }
 
  public void updateinfo(int completesize,int threadid,string url){
    sqlitedatabase db = dbhelper.getwritabledatabase();
    string sql ="update download_info set complete_size=? where thread_id=? and url=?";
    db.execsql(sql, new object[]{completesize,threadid,url});
  }
 
  public void closedb(){
    dbhelper.close();
  }
 
}

當前狀態保存類 loadinfo.java

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package entity;
 
public class loadinfo {
  private int filesize;
  private int completesize; 
  private string url;
  public loadinfo(int fs,int csize,string address){   
    filesize=fs;   
    completesize = csize;     
    url=address;
  
  /**
   * @return the filesize
   */
  public int getfilesize() {
    return filesize;
  }
  /**
   * @param filesize the filesize to set
   */
  public void setfilesize(int filesize) {
    this.filesize = filesize;
  }
  /**
   * @return the completesize
   */
  public int getcompletesize() {
    return completesize;
  }
 
  /**
   * @param completesize the completesize to set
   */
  public void setcompletesize(int completesize) {
    this.completesize = completesize;
  }
 
  /**
   * @return the url
   */
  public string geturl() {
    return url;
  }
 
  /**
   * @param url the url to set
   */
  public void seturl(string url) {
    this.url = url;
  }
}

下載助手類:downloader.java

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
package com.winton.downloadmanager;
 
import java.io.file;
import java.io.ioexception;
import java.io.inputstream;
import java.io.randomaccessfile;
import java.net.httpurlconnection;
import java.net.malformedurlexception;
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 db.dao;
import entity.downloadinfo;
import entity.loadinfo;
 
public class downloader {
  private string url;
  private string localpath;
  private int threadcount;
  private handler mhanler;
  private dao dao;
  private int filesize;
 
  private list<downloadinfo> infos;
 
  private final static int init = 1;
 
  private final static int downloading =2;
 
  private final static int pause =3;
 
  private int state = init;
 
  public downloader(string address,string lpath,int thcount,context context,handler handler){
    url =address;
    localpath = lpath;
    threadcount = thcount;
    mhanler = handler;
    dao = new dao(context);
  }
 
  public boolean isdownloading(){
    return state == downloading;
  }
 
  public loadinfo getdownloadinfos(){
    if(isfirstdownload(url)){
      init();
      int range = filesize/threadcount;
      infos = new arraylist<downloadinfo>();
      for(int i=0;i<=threadcount-1;i++){
        downloadinfo info = new downloadinfo(i, i*range, (i+1)*range-1, 0, url);
        infos.add(info);
      }
      dao.saveinfo(infos);
      return new loadinfo(filesize, 0, url);
    }else{
      infos = dao.getinfo(url);
      int size = 0;
      int completesize =0;
      for(downloadinfo info:infos){
        completesize += info.getcompletesize();
        size += info.getendpos()-info.getstartpos()+1;
      }
      return new loadinfo(size, completesize, url);
    }
  }
  public boolean isfirstdownload(string url){
    return dao.isnewtask(url);
  }
 
  public void init(){
    try {
      url murl = new url(this.url);
      httpurlconnection connection = (httpurlconnection)murl.openconnection();
      connection.setconnecttimeout(5000);
      connection.setrequestmethod("get");
      filesize = connection.getcontentlength();
 
      file file = new file(localpath);
      if(!file.exists()){
        file.createnewfile();
      }
      randomaccessfile accessfile = new randomaccessfile(file, "rwd");
      accessfile.setlength(filesize);
      accessfile.close();
      connection.disconnect();
 
    } catch (malformedurlexception e) {
      // todo auto-generated catch block
      e.printstacktrace();
    } catch (ioexception e) {
      // todo auto-generated catch block
      e.printstacktrace();
    }
  }
 
  public void download(){
    if(infos != null){
      if(state ==downloading){
        return;
      }
      state = downloading;
      for(downloadinfo info:infos){
        new downloadthread(info.getthreadid(), info.getstartpos(), info.getendpos(), info.getcompletesize(), info.geturl()).start();
 
      }
    }
  }
 
  class downloadthread extends thread{
 
    private int threadid;
    private int startpos;
    private int endpos;
    private int completesize;
    private string url;
 
    public downloadthread(int tid,int sp,int ep,int csize,string address) {
      // todo auto-generated constructor stub
      threadid=tid;
      startpos=sp;
      endpos = ep;
      completesize = csize;
      url = address;
    }
 
    @override
    public void run() {
      // todo auto-generated method stub
      httpurlconnection connection = null;
      randomaccessfile randomaccessfile = null;
      inputstream is = null;
 
      try {
        url murl = new url(url);
        connection = (httpurlconnection)murl.openconnection();
        connection.setconnecttimeout(5000);
        connection.setrequestmethod("get");
        connection.setrequestproperty("range", "bytes="+(startpos+completesize)+"-"+endpos);
        randomaccessfile = new randomaccessfile(localpath, "rwd");
        randomaccessfile.seek(startpos+completesize);
        is=connection.getinputstream();
        byte[] buffer = new byte[4096];
        int length =-1;
        while((length=is.read(buffer)) != -1){
          randomaccessfile.write(buffer, 0, length);
          completesize +=length;
          dao.updateinfo(threadid, completesize, url);
          message msg = message.obtain();
          msg.what=1;
          msg.obj=url;
          msg.arg1=length;
          mhanler.sendmessage(msg);
          if(state==pause){
            return;
          }
        }
      } catch (malformedurlexception e) {
        // todo auto-generated catch block
        e.printstacktrace();
      } catch (ioexception e) {
        // todo auto-generated catch block
        e.printstacktrace();
      }finally{
        try {
          is.close();
          randomaccessfile.close();
          connection.disconnect();
          dao.closedb();
        } catch (ioexception e) {
          // todo auto-generated catch block
          e.printstacktrace();
        }
 
      }
 
    }
 
  }
  public void delete(string url){
    dao.deleteinfo(url);
  }
  public void reset(){
    state=init;
  }
  public void pause(){
    state=pause;
  }
 
}

view呈現類:mainactivity.java

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.winton.downloadmanager;
 
import android.app.activity;
import android.os.bundle;
import android.os.environment;
import android.os.handler;
import android.os.message;
import android.view.view;
import android.view.view.onclicklistener;
import android.widget.button;
import android.widget.progressbar;
import android.widget.textview;
import android.widget.toast;
import entity.loadinfo;
 
public class mainactivity extends activity implements onclicklistener{
  private textview name;
 
  private progressbar process;
 
  private button start,stop;
  private downloader downloader;
 
  //處理下載進度ui的
  handler handler = new handler(){
    public void handlemessage(android.os.message msg) {
      if(msg.what==1){
        name.settext((string)msg.obj);
        int lenght = msg.arg1;
        process.incrementprogressby(lenght);
      }
      if(msg.what==2){
        int max =msg.arg1;
        process.setmax(max);
        toast.maketext(getapplicationcontext(), max+"", 1).show();
      }
    };
  };
  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);
    name=(textview)findviewbyid(r.id.tv_name);
    process=(progressbar)findviewbyid(r.id.pb_download);
    start = (button)findviewbyid(r.id.bt_start);
    stop = (button)findviewbyid(r.id.bt_stop);
    start.setonclicklistener(this);
    stop.setonclicklistener(this);
    downloader=new downloader("http://img4.duitang.com/uploads/item/201206/11/20120611174542_5krmj.jpeg", environment.getexternalstoragedirectory().getpath()+"/test1.jpg", 1, getapplicationcontext(), handler);
  }
 
  @override
  public void onclick(view v) {
    // todo auto-generated method stub
    if(v==start){
      new thread(new runnable() {
 
        @override
        public void run() {
          // todo auto-generated method stub
          loadinfo loadinfo = downloader.getdownloadinfos();
          message msg =handler.obtainmessage();
          msg.what=2;
          msg.arg1=loadinfo.getfilesize();
          handler.sendmessage(msg);
          downloader.download();
        }
      }).start();
      return;
    }
    if(v==stop){
      downloader.pause();
      return;
    }
  
}

運行效果

Android實現斷點下載的方法

總體比較簡單,基本實現了 斷點下載的功能,而且開啟了多個線程去實現分塊下載,對初學的同學有一定的幫助。

這些代碼我也是從網上各種搜集而來,自己親自動手敲了一遍,并做了一些小的改動,對整個斷點下載的過程有了一個深刻的認識。因此平時要多敲代碼,善于總結,必能有所收獲。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 失禁尿丝袜vk | 欧美综合精品一区二区三区 | 四虎在线永久免费视频网站 | 手机在线伦理片 | 暖暖免费高清完整版观看日本 | 男人午夜免费视频 | 亚洲日本久久一区二区va | hd最新国产人妖ts视频 | 亚洲视频在线免费 | 日本暖暖视频在线观看 | 亚洲精品国产综合久久一线 | 91久久国产露脸精品 | 国产99久久久国产精品成人 | 国产成人精品一区二三区2022 | 变态人shou交小说 | 婷婷色在线播放 | 国产日韩欧美成人 | 国色天香社区视频在线观看免费完整版 | 国产精品欧美一区二区 | 欧美精品一区二区三区免费观看 | 精品国产一区二区三区久久影院 | 激情五色月 | 好男人在线观看免费高清2019韩剧 | 国产激情一区二区三区四区 | 午夜人妻理论片天堂影院 | 精品一区二区三区波多野结衣 | 成人黄色a级片 | 精品日韩欧美一区二区三区 | 小泽玛丽av无码观看 | 国内永久第一免费福利视频 | 国产精品日韩欧美在线 | 三星w699| 日韩精品中文字幕视频一区 | 日本大片免a费观看在线 | 午夜福利体检 | 激情视频亚洲 | 美女的隐私视频免费看软件 | 爽好舒服快想要免费看 | 岛国片免费观看 | 嫩草影院永久入口在线观看 | 无人区尖叫之夜美女姐姐视频 |