Welcome

首页 / 移动开发 / Android / android使用AsyncTask实现多线程下载实例

AsyncTask不仅方便我们在子线程中对UI进行更新操作,还可以借助其本身的线程池来实现多线程任务。下面是一个使用AsyncTask来实现的多线程下载例子。
01 效果图

02 核心类 - DownloadTask.class
public class DownloadTask extends AsyncTask<String, Integer, Integer> {public static final int TYPE_SUCCESS = 0;public static final int TYPE_FAILURE = 1;public static final int TYPE_PAUSE = 2;public static final int TYPE_CANCEL = 3;public int positionDownload;private boolean isPaused = false;private boolean isCancelled = false;private DownloadListener downloadListener;private int lastProgress;public DownloadTask(DownloadListener downloadListener){this.downloadListener = downloadListener;}public void setDownloadListener(DownloadListener downloadListener){this.downloadListener = downloadListener;}@Overrideprotected Integer doInBackground(String... params) {InputStream is = null;RandomAccessFile savedFile = null;File file = null;long downloadLength = 0;String downloadUrl = params[0];positionDownload = Integer.parseInt(params[1]);String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/"));String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();file = new File(directory + fileName);if(file.exists()){downloadLength = file.length();}long contentLength = getContentLength(downloadUrl);if(contentLength == 0){return TYPE_FAILURE;} else if(contentLength == downloadLength){return TYPE_SUCCESS;}OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().addHeader("RANGE", "bytes="+downloadLength+"-").url(downloadUrl).build();try {Response response = client.newCall(request).execute();if(response != null){is = response.body().byteStream();savedFile = new RandomAccessFile(file, "rw");savedFile.seek(downloadLength);byte[] buffer = new byte[1024];int total = 0;int length;while((length = is.read(buffer)) != -1){if(isCancelled){response.body().close();return TYPE_CANCEL;} else if(isPaused) {response.body().close();return TYPE_PAUSE;}total += length;savedFile.write(buffer, 0, length);int progress = (int) ((total + downloadLength) * 100 / contentLength);int currentDownload = (int) (total + downloadLength);publishProgress(positionDownload, progress, currentDownload, (int) contentLength);}response.body().close();return TYPE_SUCCESS;}} catch (IOException e) {e.printStackTrace();} finally {try {if(is != null) is.close();if(savedFile != null) savedFile.close();if(isCancelled && file != null) file.delete();} catch (IOException e) {e.printStackTrace();}}return TYPE_FAILURE;}@Overrideprotected void onProgressUpdate(Integer... values) {int progress = values[1];if(progress > lastProgress){downloadListener.onProgress(values[0], progress, values[2], values[3]);lastProgress = progress;}}@Overrideprotected void onPostExecute(Integer status) {switch (status){case TYPE_SUCCESS:downloadListener.onSuccess(positionDownload);break;case TYPE_FAILURE:downloadListener.onFailure();break;case TYPE_PAUSE:downloadListener.onPause();break;case TYPE_CANCEL:downloadListener.onCancel();break;}}public void pauseDownload(){isPaused = true;}public void cancelDownload(){isCancelled = true;}private long getContentLength(String downloadUrl) {OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url(downloadUrl).build();Response response = null;try {response = client.newCall(request).execute();if(response != null && response.isSuccessful()){long contentLength = response.body().contentLength();response.body().close();return contentLength;}} catch (IOException e) {e.printStackTrace();}return 0;}}
03 核心类 - DownloadService.class
public class DownloadService extends Service {private Map<String, DownloadTask> downloadTaskMap = new HashMap<>();private DownloadBinder mBinder = new DownloadBinder();@Overridepublic IBinder onBind(Intent intent) {return mBinder;}private Notification getNotification(String title, int progress) {Intent intent = new Intent(this, MainActivity.class);PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);NotificationCompat.Builder builder = new NotificationCompat.Builder(this);builder.setSmallIcon(R.mipmap.ic_launcher);builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));builder.setContentIntent(pendingIntent);builder.setContentTitle(title);if(progress > 0){builder.setContentText(progress + "%");builder.setProgress(100, progress, false);}return builder.build();}private NotificationManager getNotificationManager() {return (NotificationManager) getSystemService(NOTIFICATION_SERVICE);}class DownloadBinder extends Binder {public void startDownload(String url, int position, DownloadListener listener){if(!downloadTaskMap.containsKey(url)){DownloadTask downloadTask = new DownloadTask(listener);downloadTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url, position+"");downloadTaskMap.put(url, downloadTask);if(downloadTaskMap.size() == 1){startForeground(1, getNotification("正在下载" + downloadTaskMap.size(), -1));} else{getNotificationManager().notify(1, getNotification("正在下载" + downloadTaskMap.size(), -1));}}}public void updateDownload(String url, DownloadListener listener){if(downloadTaskMap.containsKey(url)){DownloadTask downloadTask = downloadTaskMap.get(url);if(downloadTask != null){downloadTask.setDownloadListener(listener);}}}public void pauseDownload(String url){if(downloadTaskMap.containsKey(url)){DownloadTask downloadTask = downloadTaskMap.get(url);if(downloadTask != null){downloadTask.pauseDownload();}downloadTaskMap.remove(url);if(downloadTaskMap.size() > 0){getNotificationManager().notify(1, getNotification("正在下载" + downloadTaskMap.size(), -1));} else {stopForeground(true);getNotificationManager().notify(1, getNotification("全部暂停下载", -1));}}}public void downloadSuccess(String url){if(downloadTaskMap.containsKey(url)){DownloadTask downloadTask = downloadTaskMap.get(url);downloadTaskMap.remove(url);if(downloadTask != null){downloadTask = null;}if(downloadTaskMap.size() > 0){getNotificationManager().notify(1, getNotification("正在下载" + downloadTaskMap.size(), -1));} else {stopForeground(true);getNotificationManager().notify(1, getNotification("下载成功", -1));}}}public boolean isDownloading(String url){if(downloadTaskMap.containsKey(url)){return true;}return false;}public void cancelDownload(String url){if(downloadTaskMap.containsKey(url)){DownloadTask downloadTask = downloadTaskMap.get(url);if(downloadTask != null){downloadTask.cancelDownload();}downloadTaskMap.remove(url);if(downloadTaskMap.size() > 0){getNotificationManager().notify(1, getNotification("正在下载" + downloadTaskMap.size(), -1));} else {stopForeground(true);getNotificationManager().notify(1, getNotification("全部取消下载", -1));}}if(url != null){String fileName = url.substring(url.lastIndexOf("/"));String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();File file = new File(directory + fileName);if(file.exists()){file.delete();Toast.makeText(DownloadService.this, "Deleted", Toast.LENGTH_SHORT).show();}}}}}
04 源码
下载地址
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。