Android的UI是单线程的,所以对于运行时间长的程序必须
异步运行。实现异步任务的一个很方便的工具是
AsyncTask。它完全隐藏了运行任务的线程的很多详细信息。
以一个例子来说明AsyncTask:
一个非常简单的应用中,有需要初始化游戏引擎,当加载内容时,显示一些插播广告图形。假设,我们希望在用户等待游戏启动时,显示一个动画背景(类似于Windows Phone 8)上的加载程序的等待界面。
当用户在点击启动按钮以后,会执行多个初始化。
问题:如果在UI线程中执行远程服务调用初始化时,整个UI界面无法执行任何其他操作。
解决:使用AsyncTask解决这个问题,代码如下:
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