It’s very common to start a background thread to perform some task and then
update the UI when finished. You could just use a thread to perform these tasks
and then use the Activity.runOnUiThread method to display that data to the user. But what
happens if you need to display progress? Posting runnables to the UI message
handler is too heavyweight for these situations. Luckily, Android includes a class
called AsyncTask designed specifically for that scenario.
You can extend the AsyncTask class to create a simple thread to perform background
tasks and publish the results on the UI thread. It includes methods for
updating the UI before and after a task has completed, along with progress updates
along the way. Here is the basic form of an AsyncTask:
private
class DownloadFilesTask
extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
while ( true) {
// Do some work
// 更新实时的任务进度
publishProgress(( int) ((i / ( float) count) * 100));
}
return result;
}
protected void onPreExecute(){
// initialize work,for example show progressbar
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog(“Result is “ + result);
}
}
protected Long doInBackground(URL... urls) {
while ( true) {
// Do some work
// 更新实时的任务进度
publishProgress(( int) ((i / ( float) count) * 100));
}
return result;
}
protected void onPreExecute(){
// initialize work,for example show progressbar
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog(“Result is “ + result);
}
}
android.os.AsyncTask<Params, Progress, Result>
Params 启动任务执行的输入参数,比如HTTP请求的URL。
Progress 后台任务执行的百分比。
Result 后台执行任务最终返回的结果,比如String。
doInBackground方法和onPostExecute的参数必须对应
You can use onPreExecute to update the UI before your task runs, onProgressUpdate
to update a UI progress indicator, and onPostExecute to update the UI when the
task finishes. These methods all run on the main UI thread, so there is no danger
in updating your views. All code runs in the doInBackground method, which you
can think of as just being the run method of a thread.
AsyncTask is most useful for quick one-off(一次性的) tasks that need to update a UI component
(such as downloading new posts from Twitter and then loading those posts
into a timeline).
下面是一个获取指定网页的演示:
public
class NetworkActivity
extends Activity{
private TextView message;
private Button open;
private EditText url;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.network);
message= (TextView) findViewById(R.id.message);
url= (EditText) findViewById(R.id.url);
open= (Button) findViewById(R.id.open);
open.setOnClickListener( new View.OnClickListener() {
public void onClick(View arg0) {
connect();
}
});
}
private void connect() {
PageTask task = new PageTask( this);
task.execute(url.getText().toString());
}
class PageTask extends AsyncTask<String, Integer, String> {
// 可变长的输入参数,与AsyncTask.exucute()对应
ProgressDialog pdialog;
public PageTask(Context context){
pdialog = new ProgressDialog(context, 0);
pdialog.setButton("cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int i) {
dialog.cancel();
}
});
pdialog.setOnCancelListener( new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
finish();
}
});
pdialog.setCancelable( true);
pdialog.setMax(100);
pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pdialog.show();
}
@Override
protected String doInBackground(String... params) {
try{
HttpClient client = new DefaultHttpClient();
// params[0]代表连接的url
HttpGet get = new HttpGet(params[0]);
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
long length = entity.getContentLength();
InputStream is = entity.getContent();
String s = null;
if(is != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[128];
int ch = -1;
int count = 0;
while((ch = is.read(buf)) != -1) {
baos.write(buf, 0, ch);
count += ch;
if(length > 0) {
// 如果知道响应的长度,调用publishProgress()更新进度
publishProgress(( int) ((count / ( float) length) * 100));
}
// 让线程休眠100ms
Thread.sleep(100);
}
s = new String(baos.toByteArray()); }
// 返回结果
return s;
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onCancelled() {
super.onCancelled();
}
@Override
protected void onPostExecute(String result) {
// 返回HTML页面的内容
message.setText(result);
pdialog.dismiss();
}
@Override
protected void onPreExecute() {
// 任务启动,可以在这里显示一个对话框,这里简单处理
message.setText(R.string.task_started);
}
@Override
protected void onProgressUpdate(Integer... values) {
// 更新进度
System.out.println(""+values[0]);
message.setText(""+values[0]);
pdialog.setProgress(values[0]);
}
}
}
private TextView message;
private Button open;
private EditText url;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.network);
message= (TextView) findViewById(R.id.message);
url= (EditText) findViewById(R.id.url);
open= (Button) findViewById(R.id.open);
open.setOnClickListener( new View.OnClickListener() {
public void onClick(View arg0) {
connect();
}
});
}
private void connect() {
PageTask task = new PageTask( this);
task.execute(url.getText().toString());
}
class PageTask extends AsyncTask<String, Integer, String> {
// 可变长的输入参数,与AsyncTask.exucute()对应
ProgressDialog pdialog;
public PageTask(Context context){
pdialog = new ProgressDialog(context, 0);
pdialog.setButton("cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int i) {
dialog.cancel();
}
});
pdialog.setOnCancelListener( new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
finish();
}
});
pdialog.setCancelable( true);
pdialog.setMax(100);
pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pdialog.show();
}
@Override
protected String doInBackground(String... params) {
try{
HttpClient client = new DefaultHttpClient();
// params[0]代表连接的url
HttpGet get = new HttpGet(params[0]);
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
long length = entity.getContentLength();
InputStream is = entity.getContent();
String s = null;
if(is != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[128];
int ch = -1;
int count = 0;
while((ch = is.read(buf)) != -1) {
baos.write(buf, 0, ch);
count += ch;
if(length > 0) {
// 如果知道响应的长度,调用publishProgress()更新进度
publishProgress(( int) ((count / ( float) length) * 100));
}
// 让线程休眠100ms
Thread.sleep(100);
}
s = new String(baos.toByteArray()); }
// 返回结果
return s;
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onCancelled() {
super.onCancelled();
}
@Override
protected void onPostExecute(String result) {
// 返回HTML页面的内容
message.setText(result);
pdialog.dismiss();
}
@Override
protected void onPreExecute() {
// 任务启动,可以在这里显示一个对话框,这里简单处理
message.setText(R.string.task_started);
}
@Override
protected void onProgressUpdate(Integer... values) {
// 更新进度
System.out.println(""+values[0]);
message.setText(""+values[0]);
pdialog.setProgress(values[0]);
}
}
}
本文参考: http://www.cnblogs.com/dawei/archive/2011/04/18/2019903.html