0

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

4

1 に答える 1

0

私自身の質問に答えて申し訳ありませんが、私が直面していた問題は再帰とは何の関係もありませんでした。私が呼び出していたクラスはクラス Activity を拡張していました。AsyncTask からそれを呼び出そうとすると、プログラムでエラーが発生しました。extends Activity をクラス定義から削除すると、再び機能し始めました。投稿失礼します。

-ニフラーX

于 2013-03-01T17:28:13.200 に答える