private final class AsyncInitGame extends AsyncTask<String, void, String>
{
private final View root;
private final Game game;
private final TextView message;
private final Drawable bg;
public AsyncInitGame(View root, Drawable bg, Game game, TextView msg)
{
this.root = root;
this.bg = bg;
this.game = game;
this.message = msg;
}
//run on the UI thread
//1. 当UI线程调用任务的execute方法时,会首先调用该方法,这里要做的操作时该任务能够对其本身和环境执行初始化,在这个例子中是安装等待启动的背景动画
@Override protected void onPreExecute()
{
if(0 >= mInFlight++){
root.setBackgroundResouce(R.anim.dots);
((AnimationDrawable)root.getBackground()).start();
}
}
//runs on the UI thread
//3. 当doInBackground方法完成时,就删除背景线程,再在UI线程中调用onPostExecute方法。
@Override protected void onPostExecute(String msg){
if(0 >= --mInFlight){
((AndimationDrawable)root.getBackground()).stop();
root.setBackgroundDrawable(bg);
}
message.setText(msg);
}
//runs on a background thread
//2. 在onPreExecute方法完成后AsyncTask创建新的背景线程,并发执行doInBackground方法。
@Override protected String doInBackground(String... args){
return (1 != args.length) || (null == args[0])) ? null : game.initialize(args[0]);
}
}private final class AsyncInitGame extends AsyncTask<String, void, String>
{
private final View root;
private final Game game;
private final TextView message;
private final Drawable bg;
public AsyncInitGame(View root, Drawable bg, Game game, TextView msg)
{
this.root = root;
this.bg = bg;
this.game = game;
this.message = msg;
}
//run on the UI thread
//1. 当UI线程调用任务的execute方法时,会首先调用该方法,这里要做的操作时该任务能够对其本身和环境执行初始化,在这个例子中是安装等待启动的背景动画
@Override protected void onPreExecute()
{
if(0 >= mInFlight++){
root.setBackgroundResouce(R.anim.dots);
((AnimationDrawable)root.getBackground()).start();
}
}
//runs on the UI thread
//3. 当doInBackground方法完成时,就删除背景线程,再在UI线程中调用onPostExecute方法。
@Override protected void onPostExecute(String msg){
if(0 >= --mInFlight){
((AndimationDrawable)root.getBackground()).stop();
root.setBackgroundDrawable(bg);
}
message.setText(msg);
}
//runs on a background thread
//2. 在onPreExecute方法完成后AsyncTask创建新的背景线程,并发执行doInBackground方法。
@Override protected String doInBackground(String... args){
return (1 != args.length) || (null == args[0])) ? null : game.initialize(args[0]);
}
} 假设AsyncTask的实现是正确的,我们单击按钮“启动”按钮只需要创建一个实例并调用它,如下所示:((Button)findViewById(R.id.start)).setOnClickListener(
new View.OnClickListener(){
@Override public void onClick(View v){
new AsyncInitGame(root, bg, game, msg).execute("basic");
}
}
);//注:该文中的代码并不全面,只是为了阐述AsyncTask
public class AsyncDBReq extends AsyncTask<PreparedStatement, Void, ResultSet>
{
@Override protected ResultSet doInBackground(PreparedStatement...q){
//implementation.....
}
@Override protected onPostExecute(ResultSet result){
//implementation
}
}
public class AsyncHttpReq extends AsyncTask<HttpRequest, Void, HttpResponse>
{
@Override protected HeepResponse doInBackground(HttpRequest.....req){
//implementaion.....
}
@Override protected void onPostExecute(HttpResponse result){
//implementaion
}
}第一个类,AsyncDBReq实例的execute方法参数是一个或者多个PreparedStatement变量。//易犯错误一、
//....some clas
int mCOunt;
public void initButton1(Button button){
mCOunt = 0;
button.setonClickListener(
new View.OnClickListener(){
@SuppressWarnings("unchecked")
@Override public void onCLick(View v){
new AsyncTask<Void, Void, Void>(){
@Override protected Void doInBackground(Void...args){
mCount++; //!!! not thread safe!!
return null;
}
}.execute();
}});
} 这里在编译时不会产生编译错误,也没有运行警告,可能甚至在bug被触发时也不会立即失败,但该代码绝对是错误的。有两个不同的线程访问变量mCount,而这两个线程之间却没有执行同步。//易犯错误二、
public void initButton(Button button, final Map<String, String> vals){
button.setOnClickListener(
new View.OnClickListener(){
@Override public void onClick(View v){
new AsyncTask<Map<String, String>, Void, Void>(){
@Override protected Void doInBackground(Map<String,String>...params){
//implementation, uses the params Map
}
}.execute(vals);
vals.clear();//this is not thread safe!!!!
}});
}错误原因:initButton的参数valse被并发引用,却没有执行同步!!!当调用AsyncTask时,它作为参数传递给execute方法。syncTask框架可以确保当调用doInBackground方法时,该引用会正确地传递给后台线程。但是对于在initButton方法中所保存并使用的vals引用,却没有办法处理。调用vals.caear修改了在另一个线程上正在使用的状态,但没有执行同步。因此,不是线程安全的。public class AsyncTaskDemoWithProgress extends Activity{
private final class AsyncInit extends AsyncTask<String, Integer, String> implements Game.InitProgressLIstener
{
private final View root;
private final Game game;
private final TextView message;
private final Drawable bg;
public AsyncInit(View root, Drawable bg, Game game, TextView msg){
this.root = root;
this.bg = bg;
this.game = game;
this.message = msg;
}
//run on the UI thread
//1. 当UI线程调用任务的execute方法时,会首先调用该方法
@Override protected void onPreExecute()
{
if(0 >= mInFlight++){
root.setBackgroundResouce(R.anim.dots);
((AnimationDrawable)root.getBackground()).start();
}
}
//runs on the UI thread
//3. 当doInBackground方法完成时,就删除背景线程,再在UI线程中调用onPostExecute方法。
@Override protected void onPostExecute(String msg){
if(0 >= --mInFlight){
((AndimationDrawable)root.getBackground()).stop();
root.setBackgroundDrawable(bg);
}
message.setText(msg);
}
//runs on its own thread
//2. 在onPreExecute方法完成后AsyncTask创建新的背景线程,并发执行doInBackground方法。
@Override protected String doInBackground(String... args){
return (1 != args.length) || (null == args[0])) ? null : game.initialize(args[0]);
}
//runs on its UI thread
@Override protected void onProgressUpdate(Integer... vals){
updateProgressBar(vals[0].intValue());
}
//runs on the UI thread
@Override public void onInitProgress(int pctComlete){
//为了正确地给UI线程发布进程状态,onInitProgress调用的是AsyncTask的publicProgress。
//AsyncTask处理UI线程的publicProgress调度细节,从而onProgressUpdate可以安全地使用View方法。
publicProgress(Integer.valueOf(pctComplete));
}
}
int mInFlight,mComplete;
/** @see android.app.Activity#onCreate(android.os.Bundle) */
@Override public void onCreate(Bundle state){
super.onCreate(state);
setContentView(R.layout.asyncdemoprogress);
final View root = findViewById(R.id.root);
final Drawable bg = root.getBackground();
final TextView msg = ((TextView)findViewById(R.id.msg));
final Game game = Game.newGame();
((Button)findViewById(R.id.start)).setOnClickListener(
new View.OnClickListener(){
@Override public void onCLick(View v){
mComplete=0;
new AsyncInit(root, bg, game, msg).execute("basic");
}});
}
void updateProgressBar(int progress){
int p = progress;
if(mComplete < p){
mComplete = p;
(ProgressBar)findViewById(R.id.progress)).setprogress(p);
}
}
}.......嗯,其实还没结束,来个总结:Android学习之——并发编程:AsyncTask和UI线程,布布扣,bubuko.com
Android学习之——并发编程:AsyncTask和UI线程
原文:http://blog.csdn.net/fu222cs98/article/details/21794807