AsyncTask的用法小结-解析xml文件实例说明

android提供了几种在其他线程中访问UI线程的方法
Activity.runOnUiThread( Runnable )
View.post( Runnable )
View.postDelayed( Runnable,long )
Hanlder
这些类或方法同样会使你的代码很复杂很难理解。然而当你需要实现一些很复杂的操作并需要频繁地更新UI时这会变得更糟糕。

为了解决这个问题,Android 1.5提供了一个工具类:AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单。相对来说AsyncTask更轻量级一些,适用于简单的异步处理,不需要借助线程和Handler即可实现。
AsyncTask是抽象类.AsyncTask定义了三种泛型类型 Params,Progress和Result。
  Params 启动任务执行的输入参数,比如HTTP请求的URL。
  Progress 后台任务执行的百分比。
  Result 后台执行任务最终返回的结果,比如String。

AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法
  1) 子类化AsyncTask
  2) 实现AsyncTask中定义的下面一个或几个方法
   onPreExecute(),该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。
   doInBackground(Params...),将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
   onProgressUpdate(Progress...),在publishProgress方法调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
   onPostExecute(Result),在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用后台的计算结果将通过该方法传递到UI thread.

为了正确的使用AsyncTask类,以下是几条必须遵守的准则:
  1) Task的实例必须在UI thread中创建
  2) execute方法必须在UI thread中调用
  3) 不要手动的调用onPreExecute(),onPostExecute(Result),doInBackground(Params...),onProgressUpdate(Progress...)这几个方法
  4) 该task只能被执行一次,否则多次调用时将会出现异常
doInBackground方法和onPostExecute的参数必须对应,这两个参数在AsyncTask声明的泛型参数列表中指定,第一个为doInBackground接受的参数,第二个为显示进度的参数,第第三个为doInBackground返回和onPostExecute传入的参数。

下面结合一个解析xml文件简单的例子来说明其用法

MainActivity.java文件

public class MainActivity extends ListActivity implements OnClickListener{
private ProgressBar progressBar;
public static final int WRODS_COUNT = 1;
public static final int WORD = 2;
private List<String> list;
private ArrayAdapter<String> wordAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
progressBar = (ProgressBar) findViewById(R.id.progress_bar);

findViewById(R.id.start_btn).setonClickListener(this);
list = new ArrayList<String>();
wordAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,list);
setlistadapter(wordAdapter);
}
@Override
public void onClick(View v) {
asynTask.execute();//启动异步处理类对象
}
private AsyncTask<XmlResourceParser,String,Void> asynTask =
new AsyncTask<XmlResourceParser,Void>(){
private int count = 0;
/*第一个在Main线程执行的AsyncTask方法,用来做初始化
onPreExecute(),该方法将在执行实际的后台操作前被UI thread调用
可以在该方法中做一些准备工作,如在界面上显示一个进度条。*/
protected void onPreExecute() {
Log.i("info","-->onPreExecute");
};
/*在doInBackground方法调用publishProgress方法后,在Main线程中执行此方法
一般用来呈现处理进度
在publishProgress方法调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,
例如通过一个进度条进行展示。*/
protected void onProgressUpdate(String...values) {
if(count != 0){
progressBar.setMax(count);
}
list.add(values[0]);
progressBar.setProgress(progressBar.getProgress()+1);
wordAdapter.notifyDataSetChanged();
setTitle("完成:"+progressBar.getProgress()*5+"%");
};
/*doInBackground将在onPreExecute 方法执行后马上执行,
方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。
可以调用 publishProgress方法来更新实时的任务进度。
方法是抽象方法,子类必须实现。*/
@Override
protected Void doInBackground(XmlResourceParser... params) {
// Todo Auto-generated method stub
//获取要解析的文档
Log.i("info","-->doInBackground");
Resources res = getResources();
XmlResourceParser xrp = res.getXml(R.xml.wrods);
while(true){
int flage = 0;//用于记录标签的类型
try {
flage = xrp.next();
if(flage == XmlPullParser.END_DOCUMENT) break;
if(flage == XmlPullParser.START_TAG){
String tagName = xrp.getName();
if("words".equals(tagName)){
/*count用于记录有多少条数据,
*xrp.getAttributeValue(0)用于获取标签名为words的属性
**/
count = Integer.parseInt(xrp.getAttributeValue(0));
}
if("word".equals(tagName)){
String text = xrp.nextText();
publishProgress(text);
}
/*注意:sleep()方法是线程类的方法调用时需要加上类来调用*/
Thread.sleep(500);
}
} catch (XmlPullParserException e) {
// Todo Auto-generated catch block
e.printstacktrace();
} catch (IOException e) {
// Todo Auto-generated catch block
e.printstacktrace();
} catch (InterruptedException e) {
// Todo Auto-generated catch block
e.printstacktrace();
}
}
return null;
}
/*最后一个在Main线程中执行的方法,一般控制试图控件显示结果内容
在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用
后台的计算结果将通过该方法传递到UI thread*/
protected void onPostExecute(Void result) {
Log.i("info","-->onPostExecute");
};
};
}

布局文件比较简单就不写了,这个例子只是简单说明异步处理,在代码上不规范,仅供参考!

运行效果如图所示:

相关文章

php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念