国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

安卓開發(fā)筆記——關(guān)于文件斷點續(xù)傳

2019-11-14 23:44:15
字體:
供稿:網(wǎng)友
安卓開發(fā)筆記——關(guān)于文件斷點續(xù)傳

什么是斷點續(xù)傳?

客戶端軟件斷點續(xù)傳指的是在下載或上傳時,將下載或上傳任務(wù)(一個文件或一個壓縮包)人為的劃分為幾個部分,每一個部分采用一個線程進行上傳或下載,如果碰到網(wǎng)絡(luò)故障,可以從已經(jīng)上傳或下載的部分開始繼續(xù)上傳下載未完成的部分,而沒有必要從頭開始上傳下載。用戶可以節(jié)省時間,節(jié)省流量,也提高速度。

我寫了個小Demo,先看下實現(xiàn)效果圖:

斷點續(xù)傳的原理?

斷點續(xù)傳其實并沒有那么神秘,它只不過是利用了HTTP傳輸協(xié)議中請求頭(REQUEST HEADER)的不同來進行斷點續(xù)傳的。

以下是我剛在百度音樂下載MP3的時候用Firebug截下來的HTTP請求頭:

Accept:image/webp,*/*;q=0.8Accept-Encoding:gzip, deflate, sdchAccept-Language:zh-CN,zh;q=0.8Connection:keep-aliveCookie:BIDUPSID=6B8AF721169ED82B182A7EE22F75BB87; BAIDUID=6B8AF721169ED82B182A7EE22F75BB87:FG=1; BDUSS=1pWS14dzl6Ry02MVJoN0toT1RlTzRIdkdBRVlsN1JJdG9OVmQ5djAybTJ1a1JWQVFBQUFBJCQAAAAAAAAAAAEAAACkSkgjTXJfTGVlX-fiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALYtHVW2LR1VaW; __xsptplus188=188.1.1428024707.1428024712.2%234%7C%7C%7C%7C%7C%23%23QdAfR9H5KZHSIGakiCWebLQCd6CjKjz5%23; locale=zh; cflag=65279%3A3; BDRCVFR[-z8N-kPXoJt]=I67x6TjHwwYf0; H_PS_PSSID=11099_13386_1439_13425_13075_10902_12953_12868_13320_12691_13410_12722_12737_13085_13325_13203_12835_13161_8498Host:b.hiphotos.baidu.comReferer:http://music.baidu.com/song/124380645User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36

這是百度音樂服務(wù)器給我返回的信息:

Age:347651Cache-Control:max-age=31536000Connection:keep-aliveContent-Length:16659Content-Type:image/jpegDate:Sat, 11 APR 2015 06:48:45 GMTError-Message:OKETag:"10487865676202532488"Expires:Wed, 06 Apr 2016 06:02:50 GMTLast-Modified:Tue, 07 Apr 2015 05:45:32 GMTOhc-Cachable:1Server:jsp3/2.0.7

這是一般的下載請求,服務(wù)器會給我們返回我們請求下載文件的長度(Content-Length),成功狀態(tài)碼為:200。

而斷點續(xù)傳是要從我們之前已經(jīng)下載好的文件位置繼續(xù)上一次的傳輸,顧名思義我們需要告訴服務(wù)器我們上一次已經(jīng)下載到哪里了,所以在我們的HTTP請求頭里要額外的包含一條信息,而這也就是斷點續(xù)傳的奧秘所在了。

這條信息為:(RANGE為請求頭屬性,X為從什么地方開始,Y為到什么地方結(jié)束)

RANGE: bytes=X-Y 

例如:

Range : 用于客戶端到服務(wù)器端的請求,可通過該字段指定下載文件的某一段大小,及其單位。典型的格式如:Range: bytes=0-499 下載第0-499字節(jié)范圍的內(nèi)容Range: bytes=500-999 下載第500-999字節(jié)范圍的內(nèi)容Range: bytes=-500 下載最后500字節(jié)的內(nèi)容Range: bytes=500- 下載從第500字節(jié)開始到文件結(jié)束部分的內(nèi)容

以上是HTTP需要注意的地方,接下來講講java里需要注意的幾個類

關(guān)于這個HTTP請求,在Java的Net包下,給我們封裝好了一系列的類,我們直接拿來使用就行了。

這是java.net.URLConnection類下的一個方法,用來設(shè)置HTTP請求頭的,Key對應(yīng)HTTP請求頭屬性,Value對應(yīng)請求頭屬性的值。

這是java.io.RandomaccessFile類,這個類的實例支持對隨機訪問文件的讀取和寫入,這個類里有個很重要的seek(long pos)方法,

這個方法可以在你設(shè)置的長度的下一個位置進行寫入,例如seek(599),那么系統(tǒng)下一次寫入的位置就是該文件的600位置。

既然是斷點續(xù)傳,那么我們自身肯定也要記錄斷點位置,所以這里數(shù)據(jù)庫也是必不可少的。

具體實現(xiàn):

好了,了解了上面的知識點后,可以開始動手寫程序了。

下面是我寫的一個小Demo,用單線程來實現(xiàn)的斷點續(xù)傳的,注釋非常全。

這是Demo的結(jié)構(gòu)圖:(實在不會畫圖,湊合著看哈)

主類(Activity):

  1 package com.example.ui;  2   3 import android.app.Activity;  4 import android.app.AlertDialog;  5 import android.app.ProgressDialog;  6 import android.app.AlertDialog.Builder;  7 import android.content.BroadcastReceiver;  8 import android.content.Context;  9 import android.content.DialogInterface; 10 import android.content.Intent; 11 import android.content.IntentFilter; 12 import android.os.Bundle; 13 import android.util.Log; 14 import android.view.View; 15 import android.view.View.OnClickListener; 16 import android.widget.Button; 17 import android.widget.ProgressBar; 18 import android.widget.TextView; 19  20 import com.example.downloadfiletest.R; 21 import com.example.entity.FileInfo; 22 import com.example.logic.DownloadService; 23  24 public class MainActivity extends Activity { 25  26     private TextView textView; 27     private ProgressBar progressBar; 28     private Button bt_start; 29     private Button bt_stop; 30  31     @Override 32     protected void onCreate(Bundle savedInstanceState) { 33         super.onCreate(savedInstanceState); 34         setContentView(R.layout.activity_main); 35         initView(); // 初始化控件 36  37         // 注冊廣播接收者 38         IntentFilter intentFilter = new IntentFilter(); 39         intentFilter.addAction(DownloadService.UPDATE); 40         registerReceiver(broadcastReceiver, intentFilter); 41  42     } 43  44     @Override 45     protected void onDestroy() { 46         super.onDestroy(); 47         // 解綁 48         unregisterReceiver(broadcastReceiver); 49     } 50  51     // 初始化控件 52     private void initView() { 53         textView = (TextView) findViewById(R.id.textView); 54         progressBar = (ProgressBar) findViewById(R.id.progressBar); 55         bt_start = (Button) findViewById(R.id.bt_start); 56         bt_stop = (Button) findViewById(R.id.bt_stop); 57         progressBar.setMax(100); 58  59         final FileInfo fileInfo = new FileInfo(0, "Best Of Joy.MP3-Michael Jackson", "http://music.baidu.com/data/music/file?link=http://yinyueshiting.baidu.com/data2/music/38264529/382643441428735661128.mp3?xcode=46e7c02e3acba184b6145f688bb9f2422c866f9e4969f410&song_id=38264344", 0, 0); 60  61         // 點擊開始下載 62         bt_start.setOnClickListener(new OnClickListener() { 63  64             @Override 65             public void onClick(View v) { 66                 Intent intent = new Intent(MainActivity.this, DownloadService.class); 67                 intent.setAction(DownloadService.START); 68                 intent.putExtra("FileInfo", fileInfo); 69                 startService(intent); 70                 textView.setText("正在下載文件:" + fileInfo.getFileName()); 71  72             } 73         }); 74  75         // 點擊停止下載 76         bt_stop.setOnClickListener(new OnClickListener() { 77  78             @Override 79             public void onClick(View v) { 80                 Intent intent = new Intent(MainActivity.this, DownloadService.class); 81                 intent.setAction(DownloadService.STOP); 82                 intent.putExtra("FileInfo", fileInfo); 83                 startService(intent); 84                 textView.setText("任務(wù)已暫停,請點擊下載繼續(xù)"); 85             } 86         }); 87  88     } 89  90     // 廣播接收者 91     BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { 92  93         @Override 94         public void onReceive(Context context, Intent intent) { 95             if (intent.getAction().equals(DownloadService.UPDATE)) { 96                 int finished = intent.getIntExtra("finished", 0); 97                 progressBar.setProgress(finished); 98                  99                 //用戶界面友好,提醒用戶任務(wù)下載完成100                 if (finished ==100) {101                     AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this);102                     builder.setTitle("任務(wù)狀態(tài)");103                     builder.setMessage("文件下載已完成!");104                     builder.setPositiveButton("確認(rèn)", new DialogInterface.OnClickListener() {105                         106                         @Override107                         public void onClick(DialogInterface dialog, int which) {108                                     progressBar.setProgress(0);109                                     textView.setText("請點擊下載");110                         }111                     });112                     builder.show();113                 }114             }115         }116     };117 }

后臺服務(wù)類(Service)

  1 package com.example.logic;  2   3 import java.io.File;  4 import java.io.IOException;  5 import java.io.RandomAccessFile;  6 import java.net.HttpURLConnection;  7 import java.net.URL;  8   9 import org.apache.http.HttpStatus; 10 import org.apache.http.client.ClientProtocolException; 11  12 import android.app.Service; 13 import android.content.Intent; 14 import android.os.Environment; 15 import android.os.Handler; 16 import android.os.IBinder; 17 import android.util.Log; 18  19 import com.example.entity.FileInfo; 20  21 public class DownloadService extends Service { 22  23     // 按鈕標(biāo)志符 24     public static final String START = "START"; 25     public static final String STOP = "STOP"; 26     // 更新進度標(biāo)志 27     public static final String UPDATE = "UPDATE"; 28     // 下載路徑(內(nèi)存卡(SD)根目錄下的/downloads/) 29     public static final String DOWNLOADPATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/downloads/"; 30     // 定義初始化文件操作標(biāo)志 31     public static final int INIT = 0; 32  33     private DownloadTask downloadTask; 34  35     private Handler handler = new Handler() { 36         public void handleMessage(android.os.Message msg) { 37             switch (msg.what) { 38             case INIT: 39                 FileInfo fileInfo = (FileInfo) msg.obj; 40                 Log.i("init", fileInfo.toString()); 41                 // 進行下載任務(wù)操作 42                 downloadTask = new DownloadTask(DownloadService.this, fileInfo); 43                 downloadTask.download(); 44                 break; 45             } 46         }; 47     }; 48  49     /** 50      * 當(dāng)Service啟動時會被調(diào)用,用來接收Activity傳送過來的數(shù)據(jù) 51      */ 52     @Override 53     public int onStartCommand(Intent intent, int flags, int startId) { 54         if (intent.getAction().equals(START)) { 55             // 當(dāng)點擊開始下載操作時 56             // 接收Activity(putExtra)過來的數(shù)據(jù) 57             FileInfo fileInfo = (FileInfo) intent.getSerializableExtra("FileInfo"); 58             Log.i(START, fileInfo.toString()); 59             new Thread(new InitFileThread(fileInfo)).start(); 60  61         } else if (intent.getAction().equals(STOP)) { 62             // 當(dāng)點擊停止下載操作時 63             FileInfo fileInfo = (FileInfo) intent.getSerializableExtra("FileInfo"); 64             Log.i(STOP, fileInfo.toString()); 65             // 暫定任務(wù) 66             if (downloadTask != null) { 67                 downloadTask.flag = true; 68             } 69         } 70  71         return super.onStartCommand(intent, flags, startId); 72     } 73  74     @Override 75     public IBinder onBind(Intent intent) { 76         return null; 77     } 78  79     // 初始化文件操作獲取網(wǎng)絡(luò)資源大小長度,開辟子線程 80     class InitFileThread implements Runnable { 81  82         private FileInfo fileInfo; 83  84         // 構(gòu)造方法,獲取文件對象 85         public InitFileThread(FileInfo fileInfo) { 86             this.fileInfo = fileInfo; 87         } 88  89         @Override 90         public void run() { 91             /* 92              * 1、打開網(wǎng)絡(luò)連接,獲取文件長度 2、創(chuàng)建本地文件,長度和網(wǎng)絡(luò)文件相等 93              */ 94             HttpURLConnection httpURLConnection = null; 95             RandomAccessFile randomAccessFile = null; 96             try { 97                 URL url = new URL(fileInfo.getUrl()); 98                 httpURLConnection = (HttpURLConnection) url.openConnection(); 99                 // 知識點:除了下載文件,其他一律用POST100                 httpURLConnection.setConnectTimeout(3000);101                 httpURLConnection.setRequestMethod("GET");102                 // 定義文件長度103                 int length = -1;104                 // 網(wǎng)絡(luò)連接成功105                 if (httpURLConnection.getResponseCode() == HttpStatus.SC_OK) {106                     length = httpURLConnection.getContentLength();107                 }108                 // 判斷是否取得文件長度109                 if (length <= 0) {110                     return;111                 }112 113                 // 創(chuàng)建文件目錄對象114                 File dir = new File(DOWNLOADPATH);115                 if (!dir.exists()) {116                     // 若目錄不存在,創(chuàng)建117                     dir.mkdir();118                 }119                 // 創(chuàng)建文件對象120                 File file = new File(dir, fileInfo.getFileName());121                 // 創(chuàng)建隨機訪問文件流 參數(shù)二為權(quán)限:讀寫刪122                 randomAccessFile = new RandomAccessFile(file, "rwd");123                 randomAccessFile.setLength(length);124                 fileInfo.setLength(length);125                 // 發(fā)送handler126                 handler.obtainMessage(INIT, fileInfo).sendToTarget();127 128             } catch (ClientProtocolException e) {129                 e.printStackTrace();130             } catch (IOException e) {131                 e.printStackTrace();132             } finally {133                 if (randomAccessFile != null) {134                     try {135                         randomAccessFile.close();136                     } catch (IOException e) {137                         e.printStackTrace();138                     }139                 }140             }141 142         }143 144     }145 146 }

下載任務(wù)類:

  1 package com.example.logic;  2   3 import java.io.File;  4 import java.io.IOException;  5 import java.io.InputStream;  6 import java.io.RandomAccessFile;  7 import java.net.HttpURLConnection;  8 import java.net.MalformedURLException;  9 import java.net.URL; 10 import java.util.List; 11  12 import org.apache.http.HttpStatus; 13  14 import android.content.Context; 15 import android.content.Intent; 16 import android.util.Log; 17  18 import com.example.dao.ThreadDAO; 19 import com.example.dao.ThreadDAOImpl; 20 import com.example.entity.FileInfo; 21 import com.example.entity.ThreadInfo; 22  23 /** 24  * 下載任務(wù)類 25  *  26  * @author Balla_兔子 27  *  28  */ 29 public class DownloadTask { 30     private Context context; 31     private ThreadDAO dao; 32     private FileInfo fileInfo; 33     // 初始化下載進度,默認(rèn)為0 34     private int finished = 0; 35  36     // 是否暫停下載標(biāo)識符 37     public boolean flag = false; 38  39     public DownloadTask(Context context, FileInfo fileInfo) { 40         this.context = context; 41         this.fileInfo = fileInfo; 42         dao = new ThreadDAOImpl(context); 43     } 44  45     public void download() { 46         // 線程信息的url和文件的url對應(yīng) 47         List<ThreadInfo> threadInfos = dao.getThreadInfo(fileInfo.getUrl()); 48         ThreadInfo threadInfo = null; 49         if (threadInfos.size() == 0) { 50             // 若數(shù)據(jù)庫無此線程任務(wù) 51             threadInfo = new ThreadInfo(0, fileInfo.getUrl(), 0, fileInfo.getLength(), 0); 52         } else { 53             threadInfo = threadInfos.get(0); 54         } 55         // 創(chuàng)建子線程進行下載 56         new Thread(new DownloadThread(threadInfo)).start(); 57     } 58  59     // 執(zhí)行下載任務(wù),開辟子線程 60     class DownloadThread implements Runnable { 61  62         private ThreadInfo threadInfo; 63  64         public DownloadThread(ThreadInfo threadInfo) { 65             this.threadInfo = threadInfo; 66         } 67  68         @Override 69         public void run() { 70             HttpURLConnection urlConnection = null; 71             InputStream inputStream = null; 72             RandomAccessFile randomAccessFile = null; 73  74             /** 75              * 執(zhí)行下載任務(wù)  76              * 1、查詢數(shù)據(jù)庫,確定是否已存在此下載線程,便于繼續(xù)下載  77              * 2、設(shè)置從哪個位置開始下載  78              * 3、設(shè)置文件的寫入位置 79              * 4、開始下載  80              * 5、廣播通知UI更新下載進度  81              * 6、暫停線程的操作  82              * 7、下載完畢,刪除數(shù)據(jù)庫信息 83              */ 84             // 1、查詢數(shù)據(jù)庫 85             if (!dao.isExists(threadInfo.getUrl(), threadInfo.getThread_id())) { 86                 // 若不存在,插入新線程信息 87                 dao.insertThread(threadInfo); 88             } 89  90             // 2、設(shè)置下載位置 91             try { 92                 URL url = new URL(threadInfo.getUrl()); 93                 urlConnection = (HttpURLConnection) url.openConnection(); 94                 // 設(shè)置連接超時時間 95                 urlConnection.setConnectTimeout(3000); 96                 urlConnection.setRequestMethod("GET"); 97  98                 // 設(shè)置請求屬性 99                 // 參數(shù)一:Range頭域可以請求實體的一個或者多個子范圍(一半用于斷點續(xù)傳),如果用戶的請求中含有range100                 // ,則服務(wù)器的相應(yīng)代碼為206。101                 // 參數(shù)二:表示請求的范圍:比如頭500個字節(jié):bytes=0-499102 103                 // 獲取線程已經(jīng)下載的進度104                 int start = threadInfo.getStart() + threadInfo.getFinished();105                 urlConnection.setRequestProperty("range", "bytes=" + start + "-" + threadInfo.getEnd());106 107                 // 3、設(shè)置文件的寫入位置108                 File file = new File(DownloadService.DOWNLOADPATH, fileInfo.getFileName());109                 randomAccessFile = new RandomAccessFile(file, "rwd");110                 // 設(shè)置從哪里開始寫入,如參數(shù)為100,那就從101開始寫入111                 randomAccessFile.seek(start);112 113                 finished += threadInfo.getFinished();114                 Intent intent = new Intent(DownloadService.UPDATE);115                 // 4、開始下載116                 if (urlConnection.getResponseCode() == HttpStatus.SC_PARTIAL_CONTENT) {117                     inputStream = urlConnection.getInputStream();118                     // 設(shè)置字節(jié)數(shù)組緩沖區(qū)119                     byte[] data = new byte[1024*4];120                     // 讀取長度121                     int len = -1;122                     // 取得當(dāng)前時間123                     long time = System.currentTimeMillis();124                     while ((len = inputStream.read(data)) != -1) {125                         // 讀取成功,寫入文件126                         randomAccessFile.write(data, 0, len);127 128                         // 避免更新過快,減緩主線程壓力,讓其0.5秒發(fā)送一次進度129                         if (System.currentTimeMillis() - time > 500) {130                             time = System.currentTimeMillis();131                             // 把當(dāng)前進度通過廣播傳遞給UI132                             finished += len;133                             Log.i("finished:", finished+"");134                             Log.i("file:", fileInfo.getLength()+"");135                             intent.putExtra("finished", finished*100 / fileInfo.getLength());136                             context.sendBroadcast(intent);137                         }138 139                         if (flag) {140                             // 暫停下載,更新進度到數(shù)據(jù)庫141                             dao.updateThread(threadInfo.getUrl(), threadInfo.getThread_id(), finished);142                             // 結(jié)束線程143                             return;144                         }145 146                     }147                     // 當(dāng)下載執(zhí)行完畢時,刪除數(shù)據(jù)庫線程信息148                     dao.deleteThread(threadInfo.getUrl(), threadInfo.getThread_id());149                 }150 151             } catch (MalformedURLException e) {152                 e.printStackTrace();153             } catch (IOException e) {154                 e.printStackTrace();155             } finally {156                 if (urlConnection != null) {157                     urlConnection.disconnect();158                 }159                 if (inputStream != null) {160                     try {161                         inputStream.close();162                     } catch (IOException e) {163                         e.printStackTrace();164                     }165                 }166                 if (randomAccessFile != null) {167                     try {168                         randomAccessFile.close();169                     } catch (IOException e) {170                         e.printStackTrace();171                     }172                 }173 174             }175 176         }177     }178 }

數(shù)據(jù)庫幫助類:

 1 package com.example.db; 2  3 import android.content.Context; 4 import android.database.sqlite.SQLiteDatabase; 5 import android.database.sqlite.SQLiteOpenHelper; 6  7 public class DBHelper extends SQLiteOpenHelper { 8     public static final String DBNAME = "download.db"; 9     public static final int VERSION = 1;10     public static final String TABLE="threadinfo";11     public static final String CREATE_DB = "create table threadinfo (_id integer primary key autoincrement,thread_id integer,url text,start integer,end integer,finished integer) ";12     public static final String DROP_DB = "drop table if exists threadinfo";13 14     public DBHelper(Context context) {15         super(context, DBNAME, null, VERSION);16     }17 18     @Override19     public void onCreate(SQLiteDatabase db) {20         db.execSQL(CREATE_DB);21 22     }23 24     @Override25     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {26         db.execSQL(DROP_DB);27         db.execSQL(CREATE_DB);28     }29 30 }

數(shù)據(jù)庫表接口類:

 1 package com.example.dao; 2  3 import java.util.List; 4  5 import com.example.entity.ThreadInfo; 6  7 public interface ThreadDAO { 8     // 新增一條線程信息 9     public void insertThread(ThreadInfo threadInfo);10 11     // 刪除一條線程信息(多線程下載,可能一個url對應(yīng)多個線程,所以需要2個條件)12     public void deleteThread(String url, int thread_id);13 14     // 修改一條線程信息15     public void updateThread(String url, int thread_id, int finished);16 17     // 查詢線程有關(guān)信息(根據(jù)url查詢下載該url的所有線程信息)18     public List<ThreadInfo> getThreadInfo(String url);19 20     // 判斷線程是否已經(jīng)存在21     public boolean isExists(String url, int thread_id);22 23 24 }

數(shù)據(jù)庫表接口實現(xiàn)類:

 1 package com.example.dao; 2  3 import java.util.ArrayList; 4 import java.util.List; 5  6 import android.content.ContentValues; 7 import android.content.Context; 8 import android.database.Cursor; 9 import android.database.sqlite.SQLiteDatabase;10 11 import com.example.db.DBHelper;12 import com.example.entity.ThreadInfo;13 14 /**15  * ThreadDAO接口實現(xiàn)類16  * 17  * @author Balla_兔子18  * 19  */20 public class ThreadDAOImpl implements ThreadDAO {21 22     private DBHelper dbHelper;23 24     public ThreadDAOImpl(Context context) {25         dbHelper = new DBHelper(context);26     }27 28     @Override29     public void insertThread(ThreadInfo threadInfo) {30         SQLiteDatabase db = dbHelper.getWritableDatabase();31         ContentValues values = new ContentValues();32         values.put("thread_id", threadInfo.getThread_id());33         values.put("url ", threadInfo.getUrl());34         values.put("start ", threadInfo.getStart());35         values.put("end ", threadInfo.getEnd());36         values.put("finished ", threadInfo.getFinished());37         db.insert(DBHelper.TABLE, null, values);38         db.close();39     }40 41     @Override42     public void deleteThread(String url, int thread_id) {43         SQLiteDatabase db = dbHelper.getWritableDatabase();44         db.delete(DBHelper.TABLE, "url=? and thread_id=?", new String[] { url, String.valueOf(thread_id) });45         db.close();46     }47 48     @Override49     public void updateThread(String url, int thread_id, int finished) {50         SQLiteDatabase db = dbHelper.getWritableDatabase();51         db.execSQL("update threadinfo set finished = ? where url = ? and thread_id=?", new Object[] { finished, url, thread_id });52         db.close();53     }54 55     @Override56     public List<ThreadInfo> getThreadInfo(String url) {57         List<ThreadInfo> list = new ArrayList<ThreadInfo>();58         SQLiteDatabase db = dbHelper.getWritableDatabase();59         Cursor cursor = db.query(DBHelper.TABLE, null, "url=?", new String[] { url }, null, null, null);60         while (cursor.moveToNext()) {61             ThreadInfo threadInfo = new ThreadInfo();62             threadInfo.setThread_id(cursor.getInt(cursor.getColumnIndex("thread_id")));63             threadInfo.setUrl(cursor.getString(cursor.getColumnIndex("url")));64             threadInfo.setStart(cursor.getInt(cursor.getColumnIndex("start")));65             threadInfo.setEnd(cursor.getInt(cursor.getColumnIndex("end")));66             threadInfo.setFinished(cursor.getInt(cursor.getColumnIndex("finished")));67             list.add(threadInfo);68         }69         cursor.close();70         db.close();71         return list;72     }73 74     @Override75     public boolean isExists(String url, int thread_id) {76         SQLiteDatabase db = dbHelper.getWritableDatabase();77         Cursor cursor = db.query(DBHelper.TABLE, null, "url=? and thread_id=?", new String[] { url, String.valueOf(thread_id) }, null, null, null);78         boolean isExists = cursor.moveToNext();79         db.close();80         return isExists;81     }82 83 }

實體類:(文件,線程)

文件實體類:

 1 package com.example.entity; 2  3 import java.io.Serializable; 4  5 public class FileInfo implements Serializable { 6  7     private int id; 8     private String fileName; 9     private String url;10     private int length;11     private int finished;12 13     public FileInfo() {14     }15 16     public FileInfo(int id, String fileName, String url, int length,17             int finished) {18         super();19         this.id = id;20         this.fileName = fileName;21         this.url = url;22         this.length = length;23         this.finished = finished;24     }25 26     public int getId() {27         return id;28     }29 30     public void setId(int id) {31         this.id = id;32     }33 34     public String getFileName() {35         return fileName;36     }37 38     public void setFileName(String fileName) {39         this.fileName = fileName;40     }41 42     public String getUrl() {43         return url;44     }45 46     public void setUrl(String url) {47         this.url = url;48     }49 50     public int getLength() {51         return length;52     }53 54     public void setLength(int length) {55         this.length = length;56     }57 58     public int getFinished() {59         return finished;60     }61 62     public void setFinished(int finished) {63         this.finished = finished;64     }65 66     @Override67     public String toString() {68         return "FileInfo [id=" + id + ", fileName=" + fileName + ", url=" + url69                 + ", length=" + length + ", finished=" + finished + "]";70     }71 72 }
View Code

線程實體類:

 1 package com.example.entity; 2  3 import java.io.Serializable; 4  5 public class ThreadInfo implements Serializable { 6  7     private int thread_id; 8     private String url; 9     private int start;10     private int end;11     private int finished;12 13     public ThreadInfo() {14     }15 16     public ThreadInfo(int thread_id, String url, int start, int end, int finished) {17         super();18         this.thread_id = thread_id;19         this.url = url;20         this.start = start;21         this.end = end;22         this.finished = finished;23     }24 25     public int getThread_id() {26         return thread_id;27     }28 29     public void setThread_id(int thread_id) {30         this.thread_id = thread_id;31     }32 33     public String getUrl() {34         return url;35     }36 37     public void setUrl(String url) {38         this.url = url;39     }40 41     public int getStart() {42         return start;43     }44 45     public void setStart(int start) {46         this.start = start;47     }48 49     public int getEnd() {50         return end;51     }52 53     public void setEnd(int end) {54         this.end = end;55     }56 57     public int getFinished() {58         return finished;59     }60 61     public void setFinished(int finished) {62         this.finished = finished;63     }64 65     @Override66     public String toString() {67         return "ThreadInfo [thread_id=" + thread_id + ", url=" + url + ", start=" + start + ", end=" + end + ", finished=" + finished + "]";68     }69 70 }
View Code

關(guān)于多線程的斷點續(xù)傳,其實原理差不多,還是一樣把一個文件分成不同區(qū)域,然后每個區(qū)域各用一條線程去執(zhí)行下載任務(wù),然后再把文件合并,改天有時間再上個Demo給大家看吧。

作者:Balla_兔子出處:http://m.survivalescaperooms.com/lichenwei/本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。正在看本人博客的這位童鞋,我看你氣度不凡,談吐間隱隱有王者之氣,日后必有一番作為!旁邊有“推薦”二字,你就順手把它點了吧,相得準(zhǔn),我分文不收;相不準(zhǔn),你也好回來找我!


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 太仓市| 东源县| 兰州市| 海阳市| 百色市| 岢岚县| 克拉玛依市| 高邮市| 永德县| 大化| 苍南县| 三河市| 娱乐| 浪卡子县| 百色市| 晋州市| 沂源县| 广灵县| 绥江县| 铅山县| 凌云县| 察隅县| 本溪市| 津市市| 房山区| 玉田县| 台安县| 博客| 乌兰浩特市| 仪陇县| 靖安县| 固镇县| 新晃| 驻马店市| 修武县| 陵川县| 抚顺县| 抚顺县| 湘西| 镇安县| 小金县|