AsyncTasks と Hanlders と Loopers について読んできましたが、コードのどこが間違っているのかまだわかりません。Tic Tac Toe グリッドを調べて、コンピューターにとって最適な動きを判断するコードを実行しようとしています。このコードをバックグラウンドで実行したいのは、時間がかかる可能性があるためです。その後、"I'm Thinking" などのテキスト ボックスを使用して 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 が 5 つになると、最初の 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 スレッドを更新していません。エラーが発生した場所を確認するためにトレースすると、クラスが見つからないと言ってコンストラクターを呼び出すと失敗します。
誰かが私を正しい方向に向けることができますか? 私の最終的な目標は、1 つのメイン スレッドと 1 つのバックグラウンド スレッドのみを使用し、コンピューターが移動する必要があるときはいつでもバックグラウンド スレッドを再利用し続けることです。このプログラムをシングルスレッドで実行すると、再帰メソッド GetBestMove が機能することがわかっています。ただし、メソッドの実行中に一部の移動で画面が長時間フリーズします。どうもありがとう。
-ニフラーX