欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android 使用AsyncTask實現(xiàn)多任務(wù)多線程斷點(diǎn)續(xù)傳下載

 更新時間:2018年05月29日 15:03:44   作者:殘劍_  
這篇文章主要介紹了Android 使用AsyncTask實現(xiàn)多任務(wù)多線程斷點(diǎn)續(xù)傳下載的相關(guān)資料,需要的朋友可以參考下

這篇博客是AsyncTask下載系列的最后一篇文章,前面寫了關(guān)于斷點(diǎn)續(xù)傳的和多線程下載的博客,這篇是在前兩篇的基礎(chǔ)上面實現(xiàn)的,有興趣的可以去看下。

  一、AsyncTask實現(xiàn)斷點(diǎn)續(xù)傳

  二、AsyncTask實現(xiàn)多線程斷點(diǎn)續(xù)傳

  這里模擬應(yīng)用市場app下載實現(xiàn)了一個Demo,因為只有一個界面,所以沒有將下載放到Service中,而是直接在Activity中創(chuàng)建。在正式的項目中,下載都是放到Service中,然后通過BroadCast通知界面更新進(jìn)度。

  上代碼之前,先看下demo的運(yùn)行效果圖吧。

  下面我們看代碼,這里每一個文件的下載定義一個Downloador來管理下載該文件的所有線程(暫停、下載等)。Downloador創(chuàng)建3個DownloadTask(這里定義每個文件分配3個線程下載)來下載該文件特定的起止位置。這里要通過文件的大小來計算每個線程所下載的起止位置,詳細(xì)可以參考《AsyncTask實現(xiàn)多線程斷點(diǎn)續(xù)傳》。

  1、Downloador類

package com.bbk.lling.multitaskdownload.downloador;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.bbk.lling.multitaskdownload.beans.AppContent;
import com.bbk.lling.multitaskdownload.beans.DownloadInfo;
import com.bbk.lling.multitaskdownload.db.DownloadFileDAO;
import com.bbk.lling.multitaskdownload.db.DownloadInfoDAO;
import com.bbk.lling.multitaskdownload.utils.DownloadUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
 * @Class: Downloador
 * @Description: 任務(wù)下載器
 * @author: lling(www.cnblogs.com/liuling)
 * @Date: 2015/10/13
 */
public class Downloador {
 public static final String TAG = "Downloador";
 private static final int THREAD_POOL_SIZE = 9; //線程池大小為9
 private static final int THREAD_NUM = 3; //每個文件3個線程下載
 private static final int GET_LENGTH_SUCCESS = 1;
 public static final Executor THREAD_POOL_EXECUTOR = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
 private List<DownloadTask> tasks;
 private InnerHandler handler = new InnerHandler();
 private AppContent appContent; //待下載的應(yīng)用
 private long downloadLength; //下載過程中記錄已下載大小
 private long fileLength;
 private Context context;
 private String downloadPath;
 public Downloador(Context context, AppContent appContent) {
 this.context = context;
 this.appContent = appContent;
 this.downloadPath = DownloadUtils.getDownloadPath();
 }
 /**
 * 開始下載
 */
 public void download() {
 if(TextUtils.isEmpty(downloadPath)) {
 Toast.makeText(context, "未找到SD卡", Toast.LENGTH_SHORT).show();
 return;
 }
 if(appContent == null) {
 throw new IllegalArgumentException("download content can not be null");
 }
 new Thread() {
 @Override
 public void run() {
 //獲取文件大小
 HttpClient client = new DefaultHttpClient();
 HttpGet request = new HttpGet(appContent.getUrl());
 HttpResponse response = null;
 try {
  response = client.execute(request);
  fileLength = response.getEntity().getContentLength();
 } catch (Exception e) {
  Log.e(TAG, e.getMessage());
 } finally {
  if (request != null) {
  request.abort();
  }
 }
 //計算出該文件已經(jīng)下載的總長度
 List<DownloadInfo> lists = DownloadInfoDAO.getInstance(context.getApplicationContext())
  .getDownloadInfosByUrl(appContent.getUrl());
 for (DownloadInfo info : lists) {
  downloadLength += info.getDownloadLength();
 }
 //插入文件下載記錄到數(shù)據(jù)庫
 DownloadFileDAO.getInstance(context.getApplicationContext()).insertDownloadFile(appContent);
 Message.obtain(handler, GET_LENGTH_SUCCESS).sendToTarget();
 }
 }.start();
 }
 /**
 * 開始創(chuàng)建AsyncTask下載
 */
 private void beginDownload() {
 Log.e(TAG, "beginDownload" + appContent.getUrl());
 appContent.setStatus(AppContent.Status.WAITING);
 long blockLength = fileLength / THREAD_NUM;
 for (int i = 0; i < THREAD_NUM; i++) {
 long beginPosition = i * blockLength;//每條線程下載的開始位置
 long endPosition = (i + 1) * blockLength;//每條線程下載的結(jié)束位置
 if (i == (THREAD_NUM - 1)) {
 endPosition = fileLength;//如果整個文件的大小不為線程個數(shù)的整數(shù)倍,則最后一個線程的結(jié)束位置即為文件的總長度
 }
 DownloadTask task = new DownloadTask(i, beginPosition, endPosition, this, context);
 task.executeOnExecutor(THREAD_POOL_EXECUTOR, appContent.getUrl());
 if(tasks == null) {
 tasks = new ArrayList<DownloadTask>();
 }
 tasks.add(task);
 }
 }
 /**
 * 暫停下載
 */
 public void pause() {
 for (DownloadTask task : tasks) {
 if (task != null && (task.getStatus() == AsyncTask.Status.RUNNING || !task.isCancelled())) {
 task.cancel(true);
 }
 }
 tasks.clear();
 appContent.setStatus(AppContent.Status.PAUSED);
 DownloadFileDAO.getInstance(context.getApplicationContext()).updateDownloadFile(appContent);
 }
 /**
 * 將已下載大小歸零
 */
 protected synchronized void resetDownloadLength() {
 this.downloadLength = 0;
 }
 /**
 * 添加已下載大小
 * 多線程訪問需加鎖
 * @param size
 */
 protected synchronized void updateDownloadLength(long size){
 this.downloadLength += size;
 //通知更新界面
 int percent = (int)((float)downloadLength * 100 / (float)fileLength);
 appContent.setDownloadPercent(percent);
 if(percent == 100 || downloadLength == fileLength) {
 appContent.setDownloadPercent(100); //上面計算有時候會有點(diǎn)誤差,算到percent=99
 appContent.setStatus(AppContent.Status.FINISHED);
 DownloadFileDAO.getInstance(context.getApplicationContext()).updateDownloadFile(appContent);
 }
 Intent intent = new Intent(Constants.DOWNLOAD_MSG);
 if(appContent.getStatus() == AppContent.Status.WAITING) {
 appContent.setStatus(AppContent.Status.DOWNLOADING);
 }
 Bundle bundle = new Bundle();
 bundle.putParcelable("appContent", appContent);
 intent.putExtras(bundle);
 context.sendBroadcast(intent);
 }
 protected String getDownloadPath() {
 return downloadPath;
 }
 private class InnerHandler extends Handler {
 @Override
 public void handleMessage(Message msg) {
 switch (msg.what) {
 case GET_LENGTH_SUCCESS :
  beginDownload();
  break;
 }
 super.handleMessage(msg);
 }
 }
}

 2、DownloadTask類

package com.bbk.lling.multitaskdownload.downloador;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import com.bbk.lling.multitaskdownload.beans.DownloadInfo;
import com.bbk.lling.multitaskdownload.db.DownloadInfoDAO;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
/**
 * @Class: DownloadTask
 * @Description: 文件下載AsyncTask
 * @author: lling(www.cnblogs.com/liuling)
 * @Date: 2015/10/13
 */
public class DownloadTask extends AsyncTask<String, Integer , Long> {
 private static final String TAG = "DownloadTask";
 private int taskId;
 private long beginPosition;
 private long endPosition;
 private long downloadLength;
 private String url;
 private Downloador downloador;
 private DownloadInfoDAO downloadInfoDAO;
 public DownloadTask(int taskId, long beginPosition, long endPosition, Downloador downloador,
  Context context) {
 this.taskId = taskId;
 this.beginPosition = beginPosition;
 this.endPosition = endPosition;
 this.downloador = downloador;
 downloadInfoDAO = DownloadInfoDAO.getInstance(context.getApplicationContext());
 }
 @Override
 protected void onPreExecute() {
 Log.e(TAG, "onPreExecute");
 }
 @Override
 protected void onPostExecute(Long aLong) {
 Log.e(TAG, url + "taskId:" + taskId + "executed");
// downloador.updateDownloadInfo(null);
 }
 @Override
 protected void onProgressUpdate(Integer... values) {
 //通知downloador增加已下載大小
// downloador.updateDownloadLength(values[0]);
 }
 @Override
 protected void onCancelled() {
 Log.e(TAG, "onCancelled");
// downloador.updateDownloadInfo(null);
 }
 @Override
 protected Long doInBackground(String... params) {
 //這里加判斷的作用是:如果還處于等待就暫停了,運(yùn)行到這里已經(jīng)cancel了,就直接退出
 if(isCancelled()) {
 return null;
 }
 url = params[0];
 if(url == null) {
 return null;
 }
 HttpClient client = new DefaultHttpClient();
 HttpGet request = new HttpGet(url);
 HttpResponse response;
 InputStream is;
 RandomAccessFile fos = null;
 OutputStream output = null;
 DownloadInfo downloadInfo = null;
 try {
 //本地文件
 File file = new File(downloador.getDownloadPath() + File.separator + url.substring(url.lastIndexOf("/") + 1));
 //獲取之前下載保存的信息
 downloadInfo = downloadInfoDAO.getDownloadInfoByTaskIdAndUrl(taskId, url);
 //從之前結(jié)束的位置繼續(xù)下載
 //這里加了判斷file.exists(),判斷是否被用戶刪除了,如果文件沒有下載完,但是已經(jīng)被用戶刪除了,則重新下載
 if(file.exists() && downloadInfo != null) {
 if(downloadInfo.isDownloadSuccess() == 1) {
  //下載完成直接結(jié)束
  return null;
 }
 beginPosition = beginPosition + downloadInfo.getDownloadLength();
 downloadLength = downloadInfo.getDownloadLength();
 }
 if(!file.exists()) {
 //如果此task已經(jīng)下載完,但是文件被用戶刪除,則需要重新設(shè)置已下載長度,重新下載
 downloador.resetDownloadLength();
 }
 //設(shè)置下載的數(shù)據(jù)位置beginPosition字節(jié)到endPosition字節(jié)
 Header header_size = new BasicHeader("Range", "bytes=" + beginPosition + "-" + endPosition);
 request.addHeader(header_size);
 //執(zhí)行請求獲取下載輸入流
 response = client.execute(request);
 is = response.getEntity().getContent();
 //創(chuàng)建文件輸出流
 fos = new RandomAccessFile(file, "rw");
 //從文件的size以后的位置開始寫入
 fos.seek(beginPosition);
 byte buffer [] = new byte[1024];
 int inputSize = -1;
 while((inputSize = is.read(buffer)) != -1) {
 fos.write(buffer, 0, inputSize);
 downloadLength += inputSize;
 downloador.updateDownloadLength(inputSize);
 //如果暫停了,需要將下載信息存入數(shù)據(jù)庫
 if (isCancelled()) {
  if(downloadInfo == null) {
  downloadInfo = new DownloadInfo();
  }
  downloadInfo.setUrl(url);
  downloadInfo.setDownloadLength(downloadLength);
  downloadInfo.setTaskId(taskId);
  downloadInfo.setDownloadSuccess(0);
  //保存下載信息到數(shù)據(jù)庫
  downloadInfoDAO.insertDownloadInfo(downloadInfo);
  return null;
 }
 }
 } catch (MalformedURLException e) {
 Log.e(TAG, e.getMessage());
 } catch (IOException e) {
 Log.e(TAG, e.getMessage());
 } finally{
 try{
 if (request != null) {
  request.abort();
 }
 if(output != null) {
  output.close();
 }
 if(fos != null) {
  fos.close();
 }
 } catch(Exception e) {
 e.printStackTrace();
 }
 }
 //執(zhí)行到這里,說明該task已經(jīng)下載完了
 if(downloadInfo == null) {
 downloadInfo = new DownloadInfo();
 }
 downloadInfo.setUrl(url);
 downloadInfo.setDownloadLength(downloadLength);
 downloadInfo.setTaskId(taskId);
 downloadInfo.setDownloadSuccess(1);
 //保存下載信息到數(shù)據(jù)庫
 downloadInfoDAO.insertDownloadInfo(downloadInfo);
 return null;
 }
}

Downloador和DownloadTask只這個例子的核心代碼,下面是關(guān)于數(shù)據(jù)庫的,因為要實現(xiàn)斷點(diǎn)續(xù)傳必須要在暫停的時候?qū)⒚總€線程下載的位置記錄下來,方便下次繼續(xù)下載時讀取。這里有兩個表,一個是存放每個文件的下載狀態(tài)的,一個是存放每個文件對應(yīng)的每個線程的下載狀態(tài)的。

  3、DBHelper

package com.bbk.lling.multitaskdownload.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
 * @Class: DBHelper
 * @Description: 數(shù)據(jù)庫幫助類
 * @author: lling(www.cnblogs.com/liuling)
 * @Date: 2015/10/14
 */
public class DBHelper extends SQLiteOpenHelper {
 public DBHelper(Context context) {
 super(context, "download.db", null, 1);
 }
 @Override
 public void onCreate(SQLiteDatabase db) {
 db.execSQL("create table download_info(_id INTEGER PRIMARY KEY AUTOINCREMENT, task_id INTEGER, "
 + "download_length INTEGER, url VARCHAR(255), is_success INTEGER)");
 db.execSQL("create table download_file(_id INTEGER PRIMARY KEY AUTOINCREMENT, app_name VARCHAR(255), "
 + "url VARCHAR(255), download_percent INTEGER, status INTEGER)");
 }
 @Override
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
 }
}

4、DownloadFileDAO,文件下載狀態(tài)的數(shù)據(jù)庫操作類

package com.bbk.lling.multitaskdownload.db;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;
import android.util.Log;
import com.bbk.lling.multitaskdownload.beans.AppContent;
import java.util.ArrayList;
import java.util.List;
/**
 * @Class: DownloadFileDAO
 * @Description: 每個文件下載狀態(tài)記錄的數(shù)據(jù)庫操作類
 * @author: lling(www.cnblogs.com/liuling)
 * @Date: 2015/10/13
 */
public class DownloadFileDAO {
 private static final String TAG = "DownloadFileDAO";
 private static DownloadFileDAO dao=null;
 private Context context;
 private DownloadFileDAO(Context context) {
 this.context=context;
 }
 synchronized public static DownloadFileDAO getInstance(Context context){
 if(dao==null){
 dao=new DownloadFileDAO(context);
 }
 return dao;
 }
 /**
 * 獲取數(shù)據(jù)庫連接
 * @return
 */
 public SQLiteDatabase getConnection() {
 SQLiteDatabase sqliteDatabase = null;
 try {
 sqliteDatabase= new DBHelper(context).getReadableDatabase();
 } catch (Exception e) {
 Log.e(TAG, e.getMessage());
 }
 return sqliteDatabase;
 }
 /**
 * 插入數(shù)據(jù)
 * @param appContent
 */
 public void insertDownloadFile(AppContent appContent) {
 if(appContent == null) {
 return;
 }
 //如果本地已經(jīng)存在,直接修改
 if(getAppContentByUrl(appContent.getUrl()) != null) {
 updateDownloadFile(appContent);
 return;
 }
 SQLiteDatabase database = getConnection();
 try {
 String sql = "insert into download_file(app_name, url, download_percent, status) values (?,?,?,?)";
 Object[] bindArgs = { appContent.getName(), appContent.getUrl(), appContent.getDownloadPercent()
  , appContent.getStatus().getValue()};
 database.execSQL(sql, bindArgs);
 } catch (Exception e) {
 Log.e(TAG, e.getMessage());
 } finally {
 if (null != database) {
 database.close();
 }
 }
 }
 /**
 * 根據(jù)url獲取下載文件信息
 * @param url
 * @return
 */
 public AppContent getAppContentByUrl(String url) {
 if(TextUtils.isEmpty(url)) {
 return null;
 }
 SQLiteDatabase database = getConnection();
 AppContent appContent = null;
 Cursor cursor = null;
 try {
 String sql = "select * from download_file where url=?";
 cursor = database.rawQuery(sql, new String[] { url });
 if (cursor.moveToNext()) {
 appContent = new AppContent(cursor.getString(1), cursor.getString(2));
 appContent.setDownloadPercent(cursor.getInt(3));
 appContent.setStatus(AppContent.Status.getByValue(cursor.getInt(4)));
 }
 } catch (Exception e) {
 Log.e(TAG, e.getMessage());
 } finally {
 if (null != database) {
 database.close();
 }
 if (null != cursor) {
 cursor.close();
 }
 }
 return appContent;
 }
 /**
 * 更新下載信息
 * @param appContent
 */
 public void updateDownloadFile(AppContent appContent) {
 if(appContent == null) {
 return;
 }
 SQLiteDatabase database = getConnection();
 try {
 Log.e(TAG, "update download_file,app name:" + appContent.getName() + ",url:" + appContent.getUrl()
  + ",percent" + appContent.getDownloadPercent() + ",status:" + appContent.getStatus().getValue());
 String sql = "update download_file set app_name=?, url=?, download_percent=?, status=? where url=?";
 Object[] bindArgs = {appContent.getName(), appContent.getUrl(), appContent.getDownloadPercent()
  , appContent.getStatus().getValue(), appContent.getUrl()};
 database.execSQL(sql, bindArgs);
 } catch (Exception e) {
 Log.e(TAG, e.getMessage());
 } finally {
 if (null != database) {
 database.close();
 }
 }
 }
 /**
 * 獲取所有下載文件記錄
 * @return
 */
 public List<AppContent> getAll() {
 SQLiteDatabase database = getConnection();
 List<AppContent> list = new ArrayList<AppContent>();
 Cursor cursor = null;
 try {
 String sql = "select * from download_file";
 cursor = database.rawQuery(sql, null);
 while (cursor.moveToNext()) {
 AppContent appContent = new AppContent(cursor.getString(1), cursor.getString(2));
 appContent.setDownloadPercent(cursor.getInt(3));
 appContent.setStatus(AppContent.Status.getByValue(cursor.getInt(4)));
 list.add(appContent);
 }
 } catch (Exception e) {
 Log.e(TAG, e.getMessage());
 } finally {
 if (null != database) {
 database.close();
 }
 if (null != cursor) {
 cursor.close();
 }
 }
 return list;
 }
 /**
 * 根據(jù)url刪除記錄
 * @param url
 */
 public void delByUrl(String url) {
 if(TextUtils.isEmpty(url)) {
 return;
 }
 SQLiteDatabase database = getConnection();
 try {
 String sql = "delete from download_file where url=?";
 Object[] bindArgs = { url };
 database.execSQL(sql, bindArgs);
 } catch (Exception e) {
 Log.e(TAG, e.getMessage());
 } finally {
 if (null != database) {
 database.close();
 }
 }
 }
}

5、DownloadInfoDAO,每個線程對應(yīng)下載狀態(tài)的數(shù)據(jù)庫操作類

package com.bbk.lling.multitaskdownload.db;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;
import android.util.Log;
import com.bbk.lling.multitaskdownload.beans.DownloadInfo;
import java.util.ArrayList;
import java.util.List;
/**
 * @Class: DownloadInfoDAO
 * @Description: 每個單獨(dú)線程下載信息記錄的數(shù)據(jù)庫操作類
 * @author: lling(www.cnblogs.com/liuling)
 * @Date: 2015/10/13
 */
public class DownloadInfoDAO {
 private static final String TAG = "DownloadInfoDAO";
 private static DownloadInfoDAO dao=null;
 private Context context;
 private DownloadInfoDAO(Context context) {
 this.context=context;
 }
 synchronized public static DownloadInfoDAO getInstance(Context context){
 if(dao==null){
 dao=new DownloadInfoDAO(context);
 }
 return dao;
 }
 /**
 * 獲取數(shù)據(jù)庫連接
 * @return
 */
 public SQLiteDatabase getConnection() {
 SQLiteDatabase sqliteDatabase = null;
 try {
 sqliteDatabase= new DBHelper(context).getReadableDatabase();
 } catch (Exception e) {
 Log.e(TAG, e.getMessage());
 }
 return sqliteDatabase;
 }
 /**
 * 插入數(shù)據(jù)
 * @param downloadInfo
 */
 public void insertDownloadInfo(DownloadInfo downloadInfo) {
 if(downloadInfo == null) {
 return;
 }
 //如果本地已經(jīng)存在,直接修改
 if(getDownloadInfoByTaskIdAndUrl(downloadInfo.getTaskId(), downloadInfo.getUrl()) != null) {
 updateDownloadInfo(downloadInfo);
 return;
 }
 SQLiteDatabase database = getConnection();
 try {
 String sql = "insert into download_info(task_id, download_length, url, is_success) values (?,?,?,?)";
 Object[] bindArgs = { downloadInfo.getTaskId(), downloadInfo.getDownloadLength(),
  downloadInfo.getUrl(), downloadInfo.isDownloadSuccess()};
 database.execSQL(sql, bindArgs);
 } catch (Exception e) {
 Log.e(TAG, e.getMessage());
 } finally {
 if (null != database) {
 database.close();
 }
 }
 }
 public List<DownloadInfo> getDownloadInfosByUrl(String url) {
 if(TextUtils.isEmpty(url)) {
 return null;
 }
 SQLiteDatabase database = getConnection();
 List<DownloadInfo> list = new ArrayList<DownloadInfo>();
 Cursor cursor = null;
 try {
 String sql = "select * from download_info where url=?";
 cursor = database.rawQuery(sql, new String[] { url });
 while (cursor.moveToNext()) {
 DownloadInfo info = new DownloadInfo();
 info.setTaskId(cursor.getInt(1));
 info.setDownloadLength(cursor.getLong(2));
 info.setDownloadSuccess(cursor.getInt(4));
 info.setUrl(cursor.getString(3));
 list.add(info);
 }
 } catch (Exception e) {
 e.printStackTrace();
 } finally {
 if (null != database) {
 database.close();
 }
 if (null != cursor) {
 cursor.close();
 }
 }
 return list;
 }
 /**
 * 根據(jù)taskid和url獲取下載信息
 * @param taskId
 * @param url
 * @return
 */
 public DownloadInfo getDownloadInfoByTaskIdAndUrl(int taskId, String url) {
 if(TextUtils.isEmpty(url)) {
 return null;
 }
 SQLiteDatabase database = getConnection();
 DownloadInfo info = null;
 Cursor cursor = null;
 try {
 String sql = "select * from download_info where url=? and task_id=?";
 cursor = database.rawQuery(sql, new String[] { url, String.valueOf(taskId) });
 if (cursor.moveToNext()) {
 info = new DownloadInfo();
 info.setTaskId(cursor.getInt(1));
 info.setDownloadLength(cursor.getLong(2));
 info.setDownloadSuccess(cursor.getInt(4));
 info.setUrl(cursor.getString(3));
 }
 } catch (Exception e) {
 Log.e(TAG, e.getMessage());
 } finally {
 if (null != database) {
 database.close();
 }
 if (null != cursor) {
 cursor.close();
 }
 }
 return info;
 }
 /**
 * 更新下載信息
 * @param downloadInfo
 */
 public void updateDownloadInfo(DownloadInfo downloadInfo) {
 if(downloadInfo == null) {
 return;
 }
 SQLiteDatabase database = getConnection();
 try {
 String sql = "update download_info set download_length=?, is_success=? where task_id=? and url=?";
 Object[] bindArgs = { downloadInfo.getDownloadLength(), downloadInfo.isDownloadSuccess(),
  downloadInfo.getTaskId(), downloadInfo.getUrl() };
 database.execSQL(sql, bindArgs);
 } catch (Exception e) {
 Log.e(TAG, e.getMessage());
 } finally {
 if (null != database) {
 database.close();
 }
 }
 }
}

具體的界面和使用代碼我就不貼代碼了,代碼有點(diǎn)多。需要的可以下載Demo的源碼看看。

  因為還沒有花太多時間去測,里面難免會有些bug,如果大家發(fā)現(xiàn)什么問題,歡迎留言探討,謝謝!  

源碼下載:https://github.com/liuling07/MultiTaskAndThreadDownload

相關(guān)文章

  • Android自定義復(fù)合控件實現(xiàn)通用標(biāo)題欄

    Android自定義復(fù)合控件實現(xiàn)通用標(biāo)題欄

    這篇文章主要為大家詳細(xì)介紹了Android自定義復(fù)合控件實現(xiàn)通用標(biāo)題欄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • android實現(xiàn)菜單三級樹效果

    android實現(xiàn)菜單三級樹效果

    這篇文章主要為大家詳細(xì)介紹了android實現(xiàn)菜單三級樹效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • 詳解Android中的NestedScrolling機(jī)制帶你玩轉(zhuǎn)嵌套滑動

    詳解Android中的NestedScrolling機(jī)制帶你玩轉(zhuǎn)嵌套滑動

    這篇文章主要給大家詳細(xì)解析了Android中的NestedScrolling機(jī)制,通過介紹該機(jī)制帶你玩轉(zhuǎn)Android中的嵌套滑動效果,文中給出了詳細(xì)的示例代碼和介紹,需要的朋友們可以參考學(xué)習(xí),下面來一起看看吧。
    2017-05-05
  • 淺談Android ANR的信息收集過程

    淺談Android ANR的信息收集過程

    ANR全稱即Application Not Responding,也就是應(yīng)用程序無響應(yīng)。這篇文章主要介紹了Android ANR的信息收集過程,感興趣的同學(xué)可以了解一下
    2021-11-11
  • Android 隱藏底部虛擬鍵的兩種方法

    Android 隱藏底部虛擬鍵的兩種方法

    本文通過實例代碼給大家講解了Android 隱藏底部虛擬鍵的兩種方法,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧
    2018-07-07
  • 詳解如何在Flutter中獲取設(shè)備標(biāo)識符

    詳解如何在Flutter中獲取設(shè)備標(biāo)識符

    這篇文章主要為大家介紹了幾種通過Flutter讀取設(shè)備信息的方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴快跟隨小編一起學(xué)習(xí)一下
    2022-04-04
  • Android 百度地圖POI搜索功能實例代碼

    Android 百度地圖POI搜索功能實例代碼

    POI(Point of Interest),中文可以翻譯為“興趣點(diǎn)”。在地理信息系統(tǒng)中,一個POI可以是一棟房子、一個商鋪、一個郵筒、一個公交站等。通過本文給大家介紹Android 百度地圖POI搜索功能實例代碼,需要的朋友參考下
    2016-02-02
  • Flutter應(yīng)用集成極光推送的實現(xiàn)示例

    Flutter應(yīng)用集成極光推送的實現(xiàn)示例

    這篇文章主要介紹了Flutter應(yīng)用集成極光推送的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • Android Listview 滑動過程中提示圖片重復(fù)錯亂的原因及解決方法

    Android Listview 滑動過程中提示圖片重復(fù)錯亂的原因及解決方法

    android中l(wèi)istview是比較常見的組件,通過本文主要給大家分析Android中Listview滾動過程造成的圖片顯示重復(fù)、錯亂、閃爍的原因及解決方法,順便跟進(jìn)Listview的緩存機(jī)制,感興趣的朋友一起看下吧
    2016-08-08
  • Android開發(fā)之ClipboardManager剪貼板功能示例

    Android開發(fā)之ClipboardManager剪貼板功能示例

    這篇文章主要介紹了Android開發(fā)之ClipboardManager剪貼板功能,結(jié)合簡單實例形式分析了Android使用ClipboardManager實現(xiàn)剪貼板功能的相關(guān)操作技巧,需要的朋友可以參考下
    2017-03-03

最新評論