我一直在閱讀有關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