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