我一直在阅读有关 AsyncTasks 和 Hanlders 和 Loopers 的信息,但我仍然无法弄清楚我的代码哪里出错了。我正在尝试运行将查看井字游戏网格并确定计算机的最佳移动的代码。我希望这段代码在后台运行,因为它可能需要一些时间,然后我可以用一个文本框更新 UI 级别,上面写着“我在想”。我已经尝试了很多不同的方法,但都没有成功。
private class PostTask extends AsyncTask<String, Integer, String> {
private Board _b;
private Welcome.Player _opp;
private int _depth;
@Override
protected void onPreExecute() {
super.onPreExecute();
}
protected void SetVars(Board b, Player p, int depth){
_b = b;
_opp = p;
_depth = depth;
}
@Override
protected String doInBackground(String... params) {
Looper.prepare();
try{
_bestMove = _b.GetBestMove(_opp,_depth);
}
catch(Exception err){
_bestMove = -1;
}
return "All done";
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(_bestMove == -1){
TextView tv = (TextView) findViewById(R.id.tv_Score);
tv.setText("Had and error, couldn't make a move.");
}
FollowUpComputerMove(this);
}
上面的代码恰好可以运行 5 次,然后它就崩溃了。当我在调试器中观看时,我看到正在创建名为 Thread<#> AsyncTask #1 的新线程。一旦我到达其中的五个 AsyncTask,它就会返回尝试抓取第一个 AsyncTask 并崩溃。当它崩溃时,我会看到 ThreadPoolExecutor.class 文件。
我还读到我不应该同时使用 AsyncTask 和 Looper 对象,所以我尝试取出 Looper.prepare() 语句,但随后我的 AsyncTask 立即失败并显示错误消息:
Can't create handler inside thread that has not called Looper.prepare() - AsyncTask inside a dialog
我反复读到您不应该尝试从 AsyncTask 更新 UI,并且上述错误通常是因为这个,但 GetBestMove 没有更新 UI 线程。当我跟踪查看错误出现的位置时,调用构造函数说它找不到类时失败。
谁能指出我正确的方向?我的最终目标是使用一个主线程和一个后台线程,并在计算机需要移动时继续重复使用后台线程。我知道当我以单线程方式运行该程序时,递归方法 GetBestMove 有效。但是在运行该方法时,某些动作的屏幕冻结时间过长。太感谢了。
-NifflerX