0

我很困惑,我尝试了两天在图像上制作动画,而我的引擎正在考虑移动(这是一个游戏应用程序)。我在 AsyncTask 对象中执行了 chooseMove() 方法,因为它是一个有点重的递归函数,可能需要一些时间,而且我想在引擎思考时旋转沙漏图像。我试着用我知道的每一种方式去做:另一个 AsyncTask、Android 自己的动画类、处理程序等。但无论我做什么,似乎我都无法让它发挥作用。如果我尝试同时执行两个线程,它只执行其中一个,同样的事情发生在 android 自己的动画类上。所以我尝试使用进度对话框来看看我没有发疯,猜猜是什么......同样的问题!我在 onPreExecute() 中显示进度对话框,但是 doInBackgroun() 永远不会完成!由于某种原因,进度对话框控制了整个应用程序。我该怎么做?我虽然进度对话框是针对这种事情的。谢谢!

编辑:这是我的异步任务类的代码。如您所见,我在 onPreExecute() 中显示了一个进度对话框,并在 onPostExecute 中将其关闭。但是 onPost 永远不会被调用,因为 doInBackground() 也永远不会被调用。

protected void onPreExecute() {
    super.onPreExecute();
    activity.setPlaying(true);
    if (android.os.Build.VERSION.SDK_INT >android.os.Build.VERSION_CODES.GINGERBREAD) {
        // only for gingerbread and newer versions
        activity.invalidateOptionsMenu();
    }
    progressDialog = new ProgressDialog(activity);
    progressDialog.setMessage("Thinking...");
    progressDialog.setIndeterminate(true);
    progressDialog.setCanceledOnTouchOutside(false);
    progressDialog.show();
}


@Override
protected Integer doInBackground(Void... arg0) {

    int engineWin = board.takeWin(board.getBoard(), engine.getNumberOfEngine());
    int opponentWin = board.takeWin(board.getBoard(), engine.getNumberOfOpponent());

    if(engineWin!=-1){
        try{
            Thread.sleep(500);
        }
        catch(Exception e){}
        return engineWin;
    }
    else if(opponentWin!=-1){
        try{
            Thread.sleep(500);
        }
        catch(Exception e){}
        return opponentWin;
    }
    else{

        if(engine.isEnginesTurn()&&!Board.checkGameOver(board.getBoard())){
            int[] newBoard = new int[42];
            System.arraycopy(board.getBoard(), 0, newBoard, 0, 42);
            return engine.chooseMove(engine.isEnginesTurn(),newBoard,-500001,500001,0,4).getMove();
        }

        else{
            return -1;
        }
    }

}





@Override
protected void onProgressUpdate(Void... values) {
    super.onProgressUpdate(values);

}


@Override
protected void onPostExecute(Integer result) {
    super.onPostExecute(result);
    progressDialog.dismiss();

    if(result!=-1){

        ballAnimTask = new BallAnimTask(activity,boardView,board,engine);
        ballAnimTask.execute(findSlotNumberByIndex(result));
    }

}

这是我在 doInBackground() 中调用的递归 chooseMove()。在我尝试显示进度对话框之前,一切正常。此功能或任何其他功能都没有问题。只有当我尝试同时制作动画或对话时,我才会遇到问题。chooseMove() 物理上在另一个类上,我只从 AsyncTask 调用它。也许这是问题所在?

public Best chooseMove(boolean side,int[]board,int alpha,int beta,int depth,int maxDepth){
    Best myBest = new Best();
    Best reply;
    int num;
    if(Board.checkGameOver(board)||depth==maxDepth){
        myBest.setScore(returnPositionScore(board));
        return myBest;
    }
    if(side){
        myBest.setScore(alpha);
        num = numberOfEngine;
    }
    else{
        myBest.setScore(beta);
        num = numberOfOpponent;
    }
    ArrayList<Integer> availableMoves = new ArrayList<Integer>();
    availableMoves = searchAvailableMoves(board);
    for(int move:availableMoves){
        board[move] = num;
        reply = chooseMove(!side,board,alpha,beta,depth+1,maxDepth);
        board[move] = 0;
        if(side&&reply.getScore()>myBest.getScore()){
            myBest.setMove(move);
            myBest.setScore(reply.getScore());
            alpha = reply.getScore();
        }
        else if(!side&&reply.getScore()<myBest.getScore()){
            myBest.setMove(move);
            myBest.setScore(reply.getScore());
            beta = reply.getScore();
        }
        if(alpha>=beta){
            return myBest;
        }
    }
    return myBest;
}
4

2 回答 2

0

只是为了获得一些灵感,这里是我成功使用的通用代码格式,用于显示水平进度条,该进度条在后台任务运行时更新。我知道它不能回答您的确切问题,但我希望它可以帮助您找到解决方案。

ProgressDialog myProgressDialog;

private void someFunctionThatStartsTheAsyncTask()
{
    new myBackgroundTask.execute(someIntegerArgument);
}

private class myBackgroundTask extends AsyncTask<Integer, Integer, Boolean>
{
    protected void onPreExecute()
    {
        myProgressDialog = new ProgressDialog(myContext);
        myProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        myProgressDialog.setTitle("Doing something in background...");
        myProgressDialog.setMessage("Please wait...");
        myProgressDialog.setCancelable(false);
        myProgressDialog.setIndeterminate(false);
        myProgressDialog.setMax(100);
        myProgressDialog.setProgress(0);
        myProgressDialog.show();
    }

    protected Boolean doInBackground(Integer... params)
    {
        int someVariable = params[0];
        boolean success;

        for (whatever loop conditions)
        {
            // some long-running stuff, setting 'success' at some point
            ...

            publishProgress(newPositionForProgressBar);
        }

        return success;
    }

    protected void onProgressUpdate(Integer... progressPosition)
    {
        myProgressDialog.setProgress(progressPosition[0]);
    }

    protected void onPostExecute(Boolean result)
    {
        myProgressDialog.dismiss();

        if (result)
        {
            //doInBackground returned true
        }
        else
        {
            //doInBackground returned false
        }
    }
}
于 2013-05-26T12:02:39.527 回答
0

如果要从内部执行任何与 UI 相关的操作,则AsyncTask需要调用AsyncTask publishProgress方法。这将在主 UI 线程中调用onProgressUpdate回调,因此您可以在那里安全地执行与 UI 相关的操作。

但是,显然onProgressUpdate无法阻止任何代码,因为您现在回到了主 UI 线程。onProgressUpdate但是您可以更新状态栏,例如,然后在再次更新之前等待下一个回调。

于 2013-05-26T10:51:08.610 回答