我一直在阅读有关AsyncTasks和Hanlders和Loopers,但我仍然无法弄清楚我的代码中出错的地方。我试图运行代码来查看Tic Tac Toe网格并确定计算机的最佳移动。我想让这段代码在后台运行,因为它可能需要一段时间,然后我可以用一个文本框来更新UI级别,这个文本框会显示“我正在思考”之类的内容。我已经尝试了很多不同的方式,但都没有成功。使用递归方法遇到AsyncTask问题
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次移动,然后崩溃。当我在调试器中观看时,我看到新创建的线程名为线程<#> AsyncTask#1。一旦我获得了其中五个AsyncTasks,它就会尝试抓取第一个AsyncTask并崩溃。当它崩溃时,我显示了ThreadPoolExecutor.class文件。
我也读过,我不应该同时使用AsyncTask和Looper对象,所以我尝试了Loooper.prepare()语句,但是随后我的AsyncTask立即失败并显示错误消息:
Can't create handler inside thread that has not called Looper.prepare() - AsyncTask inside a dialog
我反复读,你不应该试图更新从的AsyncTask的UI,并且经常出现上述错误是因为这一点,但GetBestMove没有更新UI线程。当我追踪到错误发生的位置时,调用一个构造函数说它找不到该类时失败。
任何人都可以指向正确的方向吗?我的最终目标是使用一个主线程和一个后台线程,并且只要计算机需要进行移动,就保持重新使用后台线程。当我以单线程的方式运行这个程序时,我知道递归方法GetBestMove有效。但是随着该方法的运行,屏幕在一些移动中冻结时间过长。非常感谢。
-NifflerX