溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么在Android中使用AsyncTask實(shí)現(xiàn)一個(gè)多任務(wù)多線程斷點(diǎn)續(xù)傳下載功能

發(fā)布時(shí)間:2021-03-26 17:45:57 來(lái)源:億速云 閱讀:165 作者:Leah 欄目:移動(dòng)開(kāi)發(fā)

怎么在Android中使用AsyncTask實(shí)現(xiàn)一個(gè)多任務(wù)多線程斷點(diǎn)續(xù)傳下載功能?相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。

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; //每個(gè)文件3個(gè)線程下載
 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; //下載過(guò)程中記錄已下載大小
 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();
 }
 /**
 * 開(kāi)始下載
 */
 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ì)算出該文件已經(jīng)下載的總長(zhǎng)度
 List<DownloadInfo> lists = DownloadInfoDAO.getInstance(context.getApplicationContext())
  .getDownloadInfosByUrl(appContent.getUrl());
 for (DownloadInfo info : lists) {
  downloadLength += info.getDownloadLength();
 }
 //插入文件下載記錄到數(shù)據(jù)庫(kù)
 DownloadFileDAO.getInstance(context.getApplicationContext()).insertDownloadFile(appContent);
 Message.obtain(handler, GET_LENGTH_SUCCESS).sendToTarget();
 }
 }.start();
 }
 /**
 * 開(kāi)始創(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;//每條線程下載的開(kāi)始位置
 long endPosition = (i + 1) * blockLength;//每條線程下載的結(jié)束位置
 if (i == (THREAD_NUM - 1)) {
 endPosition = fileLength;//如果整個(gè)文件的大小不為線程個(gè)數(shù)的整數(shù)倍,則最后一個(gè)線程的結(jié)束位置即為文件的總長(zhǎng)度
 }
 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;
 }
 /**
 * 添加已下載大小
 * 多線程訪問(wèn)需加鎖
 * @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); //上面計(jì)算有時(shí)候會(huì)有點(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(),判斷是否被用戶刪除了,如果文件沒(méi)有下載完,但是已經(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è)置已下載長(zhǎng)度,重新下載
 downloador.resetDownloadLength();
 }
 //設(shè)置下載的數(shù)據(jù)位置beginPosition字節(jié)到endPosition字節(jié)
 Header header_size = new BasicHeader("Range", "bytes=" + beginPosition + "-" + endPosition);
 request.addHeader(header_size);
 //執(zhí)行請(qǐng)求獲取下載輸入流
 response = client.execute(request);
 is = response.getEntity().getContent();
 //創(chuàng)建文件輸出流
 fos = new RandomAccessFile(file, "rw");
 //從文件的size以后的位置開(kāi)始寫(xiě)入
 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ù)庫(kù)
 if (isCancelled()) {
  if(downloadInfo == null) {
  downloadInfo = new DownloadInfo();
  }
  downloadInfo.setUrl(url);
  downloadInfo.setDownloadLength(downloadLength);
  downloadInfo.setTaskId(taskId);
  downloadInfo.setDownloadSuccess(0);
  //保存下載信息到數(shù)據(jù)庫(kù)
  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í)行到這里,說(shuō)明該task已經(jīng)下載完了
 if(downloadInfo == null) {
 downloadInfo = new DownloadInfo();
 }
 downloadInfo.setUrl(url);
 downloadInfo.setDownloadLength(downloadLength);
 downloadInfo.setTaskId(taskId);
 downloadInfo.setDownloadSuccess(1);
 //保存下載信息到數(shù)據(jù)庫(kù)
 downloadInfoDAO.insertDownloadInfo(downloadInfo);
 return null;
 }
}

Downloador和DownloadTask只這個(gè)例子的核心代碼,下面是關(guān)于數(shù)據(jù)庫(kù)的,因?yàn)橐獙?shí)現(xiàn)斷點(diǎn)續(xù)傳必須要在暫停的時(shí)候?qū)⒚總€(gè)線程下載的位置記錄下來(lái),方便下次繼續(xù)下載時(shí)讀取。這里有兩個(gè)表,一個(gè)是存放每個(gè)文件的下載狀態(tài)的,一個(gè)是存放每個(gè)文件對(duì)應(yīng)的每個(gè)線程的下載狀態(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ù)庫(kù)幫助類
 * @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ù)庫(kù)操作類

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: 每個(gè)文件下載狀態(tài)記錄的數(shù)據(jù)庫(kù)操作類
 * @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ù)庫(kù)連接
 * @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,每個(gè)線程對(duì)應(yīng)下載狀態(tài)的數(shù)據(jù)庫(kù)操作類

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: 每個(gè)單獨(dú)線程下載信息記錄的數(shù)據(jù)庫(kù)操作類
 * @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ù)庫(kù)連接
 * @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();
 }
 }
 }
}

看完上述內(nèi)容,你們掌握怎么在Android中使用AsyncTask實(shí)現(xiàn)一個(gè)多任務(wù)多線程斷點(diǎn)續(xù)傳下載功能的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI