AsyncTask提供了简单易用的方式,执行后台操作并更新UI。
AsyncTask的3个泛型
- Param 传入数据类型
- Progress 更新UI数据类型
- Result 处理结果类型
AsyncTask的4个步骤
- onPreExecute 执行前的操作
- doInBackGround 后台执行的操作
- onProgressUpdate 更新UI操作
- onPostExecute 执行后的操作
示例代码:
下载远端资源,需要INTERNET权限
将资源写入到SD,需要WRITE_EXTERNAL_STORAGE权限
在AndroidManifest.xml中进行如下配置
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
功能:
异步下载,并根据下载进步更新ProgresBar,下载完成后显示图像
package lizhen.download;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.os.AsyncTask;
public class DownloadAsyncTask extends AsyncTask<String, Integer, Boolean>{
protected int size;
protected String errorMessage;
@Override
protected Boolean doInBackground(String... params) {
String url = params[0]; //資源地址
String path = params[1]; //目標路徑
try {
InputStream source = requestInputStream(url); //請求源文件InputStream
/*
* 創建文件寫入數據,并更新進度
* */
fileWrite(source, path);
} catch (ClientProtocolException e) {
errorMessage = e.getMessage();
cancel(true);
return false;
} catch (IOException e) {
errorMessage = e.getMessage();
cancel(true);
return false;
}
return true;
}
/**
* 文件寫入
* @param in 數據源輸入流
* @param path 文件路徑
* @param listener 下載進度監聽器
* */
private void fileWrite(InputStream in, String path) throws IOException {
File file = createFile(path);
FileOutputStream fileOutputStream = new FileOutputStream(file);
byte buffer[] = new byte[1024];
int progress = 0;
int readBytes = 0;
while ((readBytes = in.read(buffer)) != -1) {
progress += readBytes;
fileOutputStream.write(buffer, 0, readBytes);
publishProgress(progress);
}
in.close();
fileOutputStream.close();
}
/**
* 根據資源URL地址取得資源輸入流
* @param url URL地址
* @return 資源輸入流
* @throws ClientProtocolException
* @throws IOException
* */
private InputStream requestInputStream(String url) throws ClientProtocolException, IOException {
InputStream result = null;
HttpGet httpGet = new HttpGet(url);
HttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = httpClient.execute(httpGet);
int httpStatusCode = httpResponse.getStatusLine().getStatusCode();
if(httpStatusCode == HttpStatus.SC_OK) {
HttpEntity httpEntity = httpResponse.getEntity();
size = (int) httpEntity.getContentLength();
result = httpEntity.getContent();
}
return result;
}
/**
* 根據文件路徑創建文件
* @param path 文件路徑
* @return 文件File實例
* @return IOException
* */
private File createFile(String path) throws IOException {
File file = new File(path);
file.createNewFile();
return file;
}
/**
* 返回錯誤信息
* @return 錯誤信息
* */
public String getErrorString() {
return this.errorMessage;
}
}
package lizhen.download;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class Download extends Activity {
private Button startButton;
private ProgressBar downloadProgressBar;
private TextView progressTextView;
private ImageView downloadImageView;
private final String source = "http://192.168.211.86/comic/test.jpg"; //源文件地址
private final String path = Environment.getExternalStorageDirectory().toString()+"/test.jpg"; //目標文件地址
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.download);
startButton = (Button) findViewById(R.id.download_StartButton);
downloadProgressBar = (ProgressBar) findViewById(R.id.download_ProgressBar);
progressTextView = (TextView) findViewById(R.id.download_ProgressTextView);
downloadImageView = (ImageView) findViewById(R.id.download_ImageView);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new DownloadTask().execute(source, path);
}
});
}
private class DownloadTask extends DownloadAsyncTask {
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
int progress = values[0];
/*
* 更新進度條和下載百分率
* */
downloadProgressBar.setMax(size);
downloadProgressBar.setProgress(progress);
int percentage = progress*100/size;
progressTextView.setText("已完成"+percentage+"%");
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if(result) {
Bitmap bitmap = BitmapFactory.decodeFile(path);
downloadImageView.setImageBitmap(bitmap);
} else {
Toast.makeText(Download.this, "Error: "+errorMessage, 1000).show();
}
}
}
}
运行结果: