讲另一种Android多线程技术——AsyncTask封装,这个可以说是把Handler进一步封
装,条理更加清晰,同样地,使用起来又稍微复杂一些。
附图:
在new的时候,AsyncTask类中有四个方法:
onPreExecute()——>doInBackground()——>onProgressUpdate()——>
onPostExecute()。
分别对应着
准备前的资源工作——>耗时操作(子线程)——>更新过程进度——>处理耗时操作
结束后的工作。
只有doinbackground方法是在子线程中进行的,其余都是UI线程,可以直接操作界
面。
如果需要更新进度,需要在doinbackground方法内调用publishProgress将进度发送给
onProgressUpdate。
我们来用asyncTask做上一次倒计时的同样项目,但是是用dialog来倒计时。
mainactivity:
package com.example.asynctasktest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private TextView main_tv,tv;
private int num;
private ProgressDialog pd;
private AlertDialog.Builder builder;
private AlertDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
main_tv=(TextView) findViewById(R.id.main_tv);
}
public void myclick(View v)
{
AsyncTask<Void, Integer, Void> task=new AsyncTask<Void, Integer, Void>(){
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Integer values=10-i;
publishProgress(values);
}
return null;
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
View view=MainActivity.this.getLayoutInflater().inflate(R.layout.item, null);
builder = new Builder(MainActivity.this);
dialog=builder.setIcon(android.R.drawable.ic_dialog_alert).setTitle("提示:").setView(view).create();
tv=(TextView) view.findViewById(R.id.tv);
dialog.show();
super.onPreExecute();
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
dialog.dismiss();
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
tv.setText(values[0]+"");
}
};
Void params=null;
task.execute(params);
}
}
说一下各个方法:
1.onPreExecute():该方法运行在UI线程当中,并且运行在UI线程当中 可以对UI空间进
行设置 。
2.String doInBackground(Void… params):
这里的Void参数对应AsyncTask中的第一个参数
这里的String返回值对应AsyncTask的第三个参数
该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改
3.onProgressUpdate(Integer progress):
- 这里的Intege参数对应AsyncTask中的第二个参数
- 在doInBackground方法当中,,每次调用publishProgress方法都会发给onProgressUpdate执行
- onProgressUpdate是在UI线程中执行,所有可以对UI空间进行操作
4.void onPostExecute(String result):
- 这里的String参数对应AsyncTask中的第三个参数(也就是接收doInBackground的返回值)
- 在doInBackground方法执行结束之后在运行,并且运行在UI线程当中 可以对UI空间进行设置
按钮的点击事件是myclick方法。
注意:
在这里用的dialog是将自己定义好的布局转为视图view,如果直接通过改变Message是
无法改变数字的,因为只发送一次Message,并没有通知更新新的Message,所以自己
定义了布局,里面是TextView来达到效果。
dialog=builder.setIcon(android.R.drawable.ic_dialog_alert).setTitle(“提示:”).setView(view).create()
这里因为每一次set之后同样也是返回Builder对象,所以可以连续设置,当然,分开写
也是可以的。