Android中AsyncTask進行後台下載檔案並在下拉式功能表顯示下載進度,androidasynctask

來源:互聯網
上載者:User

Android中AsyncTask進行後台下載檔案並在下拉式功能表顯示下載進度,androidasynctask

在開發過程中,總會需要從網路上下載檔案,有時候還需要將下載進度顯示在下拉式功能表中。

現在寫了一個Demo,封裝了AsyncTask下載檔案和進度顯示的代碼,以後在做項目的時候能夠直接進行使用。



主介面只有一個按鈕,比較簡單:

/ layout / activity_main.xml :

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <Button        android:id="@+id/button"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentLeft="true"        android:layout_alignParentTop="true"        android:text="點擊下載" /></RelativeLayout>


MainActivity:其中的思路解釋均在代碼中:

import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity {private Handler mHandler = new Handler();private AsyncTaskUtil mDownloadAsyncTask;private Button mButton;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mButton = (Button) findViewById(R.id.button);mButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {//AsyncTask非同步下載任務mDownloadAsyncTask = new AsyncTaskUtil(MainActivity.this, mHandler);mDownloadAsyncTask.execute("http://apps.wandoujia.com/apps/com.sec.print.mobileprint/download", "Mobile Print.apk");//必須傳入兩個參數——參數1:url;參數2:檔案名稱(可以為null)}});}}

以上只要通過建立一個AsyncTaskUtil的對象,傳入url和檔案名稱便能後台下載檔案病顯示下載進度,是不是很方面?具體的代碼解析如下:


AsyncTaskRunnable:用於handler.post(Runnable)方法來更新UI,下載進度主要通過NotificationManager、Notification和RemoteView來顯示、更新下載的進度,不懂的同學需要google一下~

import java.text.DecimalFormat;import android.app.Notification;import android.app.NotificationManager;import android.content.Context;import android.util.Log;import android.widget.RemoteViews;import android.widget.Toast;public class AsyncTaskRunnable implements Runnable{public static final String TAG = "AsyncTaskRunnable";//主線程的activityprivate Context mContext;//notification的狀態:更新 or 失敗 or 成功private int mStatus;//notification的下載比例private float mSize;//管理下拉式功能表的通知資訊private NotificationManager mNotificationManager;//下拉式功能表的通知資訊private Notification mNotification;//下拉式功能表的通知資訊的viewprivate RemoteViews mRemoteViews;    //下拉式功能表的通知資訊的種類idprivate static final int NOTIFICATION_ID = 1;//設定比例和資料public void setDatas(int status , float size) {this.mStatus = status;this.mSize = size;}//初始化public AsyncTaskRunnable(Context context) {this.mContext = context;mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);//初始化下拉式功能表的通知資訊mNotification = new Notification();mNotification.icon = R.drawable.ic_launcher;//設定下載進度的iconmNotification.tickerText = mContext.getResources().getString(R.string.app_name); //設定下載進度的titlemRemoteViews = new RemoteViews(mContext.getPackageName(), R.layout.down_notification);//對於RemoteView的使用,不懂的需要尋找googlemRemoteViews.setImageViewResource(R.id.id_download_icon, R.drawable.ic_launcher);}@Overridepublic void run() {//通過判斷不同的狀態:更新中/下載失敗/下載成功 更新下拉式功能表的通知資訊switch (mStatus) {case AsyncTaskUtil.NOTIFICATION_PROGRESS_FAILED://下載失敗mNotificationManager.cancel(NOTIFICATION_ID);break;case AsyncTaskUtil.NOTIFICATION_PROGRESS_SUCCEED://下載成功mRemoteViews.setTextViewText(R.id.id_download_textview, "Download completed ! ");mRemoteViews.setProgressBar(R.id.id_download_progressbar, 100, 100, false);mNotification.contentView = mRemoteViews;mNotificationManager.notify(NOTIFICATION_ID, mNotification);mNotificationManager.cancel(NOTIFICATION_ID);Toast.makeText(mContext, "Download completed ! ", Toast.LENGTH_SHORT).show();break;case AsyncTaskUtil.NOTIFICATION_PROGRESS_UPDATE://更新中DecimalFormat format = new DecimalFormat("0.00");//數字格式轉換String progress = format.format(mSize);Log.d(TAG, "the progress of the download " + progress);mRemoteViews.setTextViewText(R.id.id_download_textview, "Download completed : " + progress + " %");mRemoteViews.setProgressBar(R.id.id_download_progressbar, 100, (int)mSize, false);mNotification.contentView = mRemoteViews;mNotificationManager.notify(NOTIFICATION_ID, mNotification);break;}}}
其中需要建立一個下載進度的布局檔案,如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:gravity="center"        android:orientation="horizontal"        android:background="@android:color/white" >        <ImageView            android:id="@+id/id_download_icon"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginRight="10dp"            android:layout_marginLeft="10dp"            android:src="@drawable/ic_launcher" />        <LinearLayout            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginRight="10dip"            android:layout_weight="1"            android:orientation="vertical" >            <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="@string/app_name"                android:textColor="@android:color/black"                android:textSize="18dip"                android:textStyle="bold" />            <ProgressBar                android:id="@+id/id_download_progressbar"                style="?android:attr/progressBarStyleHorizontal"                android:layout_width="fill_parent"                android:layout_height="wrap_content"                android:layout_marginTop="5dp"                android:max="100"                android:progress="0"                android:secondaryProgress="0" />            <TextView                android:id="@+id/id_download_textview"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="Download completed : "                 android:textColor="@android:color/black"                android:textSize="12dip"                android:textStyle="bold" />        </LinearLayout>    </LinearLayout></LinearLayout>


非同步下載類:AsyncTaskUtil用於下載檔案:
import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import java.net.URL;import java.net.URLConnection;import java.util.Timer;import java.util.TimerTask;import android.content.Context;import android.os.AsyncTask;import android.os.Environment;import android.os.Handler;import android.util.Log;import android.widget.Toast;public class AsyncTaskUtil extends AsyncTask<String, Double, Boolean> {public static final String TAG = "AsyncTaskUtil";public static final int NOTIFICATION_PROGRESS_UPDATE = 0x10;//用於更新下載進度的標誌public static final int NOTIFICATION_PROGRESS_SUCCEED = 0x11;//表示下載成功public static final int NOTIFICATION_PROGRESS_FAILED = 0x12;//表示下載失敗//URLprivate String mUrl;//activityprivate Context mContext;//任務定時器private Timer mTimer;//定時任務private TimerTask mTask;//主線程傳遞過來的handlerprivate Handler  mHandler;//所要下載的檔案大小private long mFileSize;//已下載的檔案大小private long mTotalReadSize;//AsyncTaskRunnable實現了Runnable介面,用於更新下載進度的顯示private AsyncTaskRunnable mRunnable;//構造方法public AsyncTaskUtil(Context context, Handler handler) {mContext = context;mHandler = handler;mTimer = new Timer();mTask = new TimerTask() {//在run方法中執行定時的任務@Overridepublic void run() {//size表示下載進度的百分比float size = (float) mTotalReadSize * 100 / (float) mFileSize;//通過AsyncTaskRunnable的setDatas方法下載的進度和狀態(更新中、失敗、成功)mRunnable.setDatas(NOTIFICATION_PROGRESS_UPDATE, size);//更新進度mHandler.post(mRunnable);}};mRunnable = new AsyncTaskRunnable(mContext);}// 執行耗時操作,params[0]為url,params[1]為檔案名稱(空則寫入null)@Overrideprotected Boolean doInBackground(String... params) {//任務定時器一定要啟動mTimer.schedule(mTask, 0, 500);try {mUrl = params[0];//建立連結URLConnection connection = new URL(mUrl).openConnection();//擷取檔案大小mFileSize = connection.getContentLength();Log.d(TAG, "the count of the url content length is : " + mFileSize);//獲得輸入資料流InputStream is = connection.getInputStream();//先建立檔案夾File fold = new File(getFolderPath());if (!fold.exists()) {fold.mkdirs();}String fileName = "";//判斷檔案名稱:使用者自訂或由url獲得if(params[1] != null){fileName = params[1];} else{fileName = getFileName(params[0]);}//檔案輸出資料流FileOutputStream fos = new FileOutputStream(new File(getFolderPath()+ fileName));byte[] buff = new byte[1024];int len;while ((len = is.read(buff)) != -1) {mTotalReadSize += len;fos.write(buff, 0, len);}fos.flush();fos.close();} catch (Exception e) {//異常,下載失敗mRunnable.setDatas(NOTIFICATION_PROGRESS_FAILED, 0);//發送顯示下載失敗mHandler.post(mRunnable);if(mTimer != null && mTask != null){mTimer.cancel();mTask.cancel();}e.printStackTrace();return false;}//下載成功mRunnable.setDatas(NOTIFICATION_PROGRESS_SUCCEED, 0);mHandler.post(mRunnable);if(mTimer != null && mTask != null){mTimer.cancel();mTask.cancel();}return true;}//由url獲得檔案名稱private String getFileName(String string) {return string.substring(string.lastIndexOf("/") + 1);}//下載檔案夾路徑private String getFolderPath() {return Environment.getExternalStorageDirectory().toString() + "/AsyncTaskDownload/";}// doInBackground方法之前調用,初始化UI@Overrideprotected void onPreExecute() {super.onPreExecute();}// 在doInBackground方法之後調用@Overrideprotected void onPostExecute(Boolean result) {super.onPostExecute(result);if (result) {Toast.makeText(mContext, "Download Completed ! ", Toast.LENGTH_SHORT).show();} else {Toast.makeText(mContext, "Download Failed ! ", Toast.LENGTH_SHORT).show();}}@Overrideprotected void onProgressUpdate(Double... values) {super.onProgressUpdate(values);}}

好了,以上就是今天分享的內容~~是時候(~﹃~)~zZ

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.