AsyncTask和handler都是android为我们提供的异步操作的类,但是AsyncTask属于轻量级的异步类,可以说是对使用handler的封装,以前使用线程异步的时候都用得handler
感觉方便简单,想想一个单一的UI更新就要实现一个类,AsyncTask还真是麻烦, 但是他对于一定规模的多条线程,多任务来说还是比较不错的,比如(规格要求不高的多图片,文件等下
载,),对于大规模的同时的还是需要用到handler.
下边就来介绍一下AsyncTask这个类:
AsyncTask直接继承于Object类,位置为android.os.AsyncTask。
AsyncTask定义了三种泛型类型 Params,Progress和Result。
Params 启动任务执行的输入参数,如HTTP请求的URL等。
Progress 后台任务完成的百分比。
Result 后台执行任务最终返回的结果。
AsyncTask使用最少要实现他的doInBackground(Params…)方法,有的说是还有onPostExecute(Result),用Eclipse给的抱错提示是前者,但是如果只是实现doInBackground(Params…),不实现后者的话,也没必要用它了,直接开个线程得了,个人感觉两种说法并不冲突.下边介绍一下他的各个方法:
要实现的:
doInBackground(Params…) 后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通常需要较长的时 间。在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。
onPostExecute(Result) 相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回
还可以实现的:
onProgressUpdate(Progress…) 可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。
onPreExecute() 这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。
onCancelled() 用户调用取消时,要做的操作
别人提醒出来的一些规则:
Task的实例必须在UI thread中创建;
execute方法必须在UI thread中调用;
不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法;
该task只能被执行一次,否则多次调用时将会出现异常;
简单代码附上:
activity_main.xml
<LinearLayout 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"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/pb_show"
android:layout_width="fill_parent"
style="?android:attr/progressBarStyleHorizontal"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tv_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<Button
android:id="@+id/bt_show"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="下载"/>
</LinearLayout>
MainActivity.java
package com.example.chen;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
public class MainActivity extends Activity {
private ProgressBar pb = null;
private Button btn = null;
private TextView tv = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pb = (ProgressBar) findViewById(R.id.pb_show);
tv = (TextView) findViewById(R.id.tv_show );
btn = (Button) findViewById(R.id.bt_show);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
PbAsyncTask pbat = new PbAsyncTask(tv,pb);
pbat.execute(0);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
PbAsyncTask.java
对各个参数的理解是关键,看注释
package com.example.chen;
import android.os.AsyncTask;
import android.widget.ProgressBar;
import android.widget.TextView;
public class PbAsyncTask extends AsyncTask<Integer, Integer, String>{
private TextView tv;
private ProgressBar pb;
public PbAsyncTask(TextView textview,ProgressBar progressbar){
this.tv = textview;
this.pb = progressbar;
}
/**
* Integer参数对应AsyncTask中的第一个参数
* String返回值对应AsyncTask的第三个参数
* 该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改
* 调用publishProgress方法触发onProgressUpdate对UI进行操作
*/
@Override
protected String doInBackground(Integer... params) {
DoInThread oit = new DoInThread();
int i = 0;
for(i=0; i<=100; i+=10){
oit.doThread();
publishProgress(i);
}
return " 看到结果了吧";
}
/**
* 运行在UI线程当中,在doInBackground(Integer... params)之前,可以改变UI控件
*/
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
tv.setText("开始执行");
}
/**
* String对应AsyncTask中的第三个参数,是doInBackground(Integer... params)返回值
* 在doInBackground方法执行结束之后在运行,他运行在UI线程当中 可以改变UI控件
*/
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
tv.setText("执行结束"+result);
}
/**
* Intege是AsyncTask的第二个参数
* 在doInBackground方法当中,,每次调用publishProgress方法都会触发onProgressUpdate执行
* onProgressUpdate是在UI线程中执行,所有可以对UI控件进行操作
*/
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
int value = values[0];
pb.setProgress(value);
}
}
耗时操作类 DoInThread.java
package com.example.chen;
public class DoInThread {
public void doThread(){
try {
Thread.sleep(500);
} catch (Exception e) {
// TODO: handle exception
}
}
}
这就是AsyncTask的运行线程,方式,有更好的理解,请完善