最近項目中要做一個帶進度條的上傳檔案的功能,學習了AsyncTask,使用起來比較友善,将幾個方法實作就行,另外做了一個很簡單的demo,希望能對大家有幫助,在程式中設好檔案路徑和伺服器IP即可。
demo下載下傳:
android異步上傳小demo.zip
demo運作截圖:
AsyncTask是抽象類,子類必須實作抽象方法doInBackground(Params... p),在此方法中實作任務的執行工作,比如聯網下載下傳或上傳。AsyncTask定義了三種泛型類型Params,Progress和Result。
1、Params 啟動任務執行的輸入參數,比如HTTP請求的URL,上傳檔案的路徑等;
2、Progress 背景任務執行的百分比;
3、Result 背景執行任務的最終傳回結果,比如String。
AsyncTask 的執行分為四個步驟,與前面定義的TaskListener類似。每一步都對應一個回調方法,需要注意的是這些方法不應該由應用程式調用,開發者需要做的就是實作這些方法。在任務的執行過程中,這些方法被自動調用。
1、onPreExecute(), 該方法将在執行實際的背景操作前被UI thread調用。可以在該方法中做一些準備工作,如在界面上顯示一個進度條。
2、doInBackground(Params...), 将在onPreExecute 方法執行後馬上執行,該方法運作在背景線程中。這裡将主要負責執行那些很耗時的背景計算工作。可以調用 publishProgress方法來更新實時的任務進度。該方法是抽象方法,子類必須實作。
3、onProgressUpdate(Progress...),在publishProgress方法被調用後,UI thread将調用這個方法進而在界面上展示任務的進展情況,例如通過一個進度條進行展示。
4、onPostExecute(Result), 在doInBackground 執行完成後,onPostExecute 方法将被UI thread調用,背景的計算結果将通過該方法傳遞到UI thread.
主程序中使用下面兩行開始異步任務:
mTask = new MyTask();
mTask.execute(filePath, url);
doInBackground()函數中,params[0]和params[1]本别對應execute()的第一個和第二個變量。
private class MyTask extends AsyncTask<String, Integer, String>{
@Override
protected void onPostExecute(String result) {
//最終結果的顯示
mTvProgress.setText(result);
}
@Override
protected void onPreExecute() {
//開始前的準備工作
mTvProgress.setText("loading...");
}
@Override
protected void onProgressUpdate(Integer... values) {
//顯示進度
mPgBar.setProgress(values[0]);
mTvProgress.setText("loading..." + values[0] + "%");
}
@Override
protected String doInBackground(String... params) {
//這裡params[0]和params[1]是execute傳入的兩個參數
String filePath = params[0];
String uploadUrl = params[1];
//下面即手機端上傳檔案的代碼
String end = "\r\n";
String twoHyphens = "--";
String boundary = "******";
try {
URL url = new URL(uploadUrl);
HttpURLConnection httpURLConnection = (HttpURLConnection) url
.openConnection();
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
httpURLConnection.setUseCaches(false);
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setConnectTimeout(6*1000);
httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
httpURLConnection.setRequestProperty("Charset", "UTF-8");
httpURLConnection.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
DataOutputStream dos = new DataOutputStream(httpURLConnection
.getOutputStream());
dos.writeBytes(twoHyphens + boundary + end);
dos
.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\""
+ filePath.substring(filePath.lastIndexOf("/") + 1)
+ "\"" + end);
dos.writeBytes(end);
//擷取檔案總大小
FileInputStream fis = new FileInputStream(filePath);
long total = fis.available();
byte[] buffer = new byte[8192]; // 8k
int count = 0;
int length = 0;
while ((count = fis.read(buffer)) != -1) {
dos.write(buffer, 0, count);
//擷取進度,調用publishProgress()
length += count;
publishProgress((int) ((length / (float) total) * 100));
//這裡是測試時為了示範進度,休眠500毫秒,正常應去掉
Thread.sleep(500);
}
fis.close();
dos.writeBytes(end);
dos.writeBytes(twoHyphens + boundary + twoHyphens + end);
dos.flush();
InputStream is = httpURLConnection.getInputStream();
InputStreamReader isr = new InputStreamReader(is, "utf-8");
BufferedReader br = new BufferedReader(isr);
@SuppressWarnings("unused")
String result = br.readLine();
dos.close();
is.close();
return "上傳成功";
}catch (Exception e) {
e.printStackTrace();
return "上傳失敗";
}
}
界面中隻要一個進度條progressBar 和一個用于顯示的TextView即可。