我很困惑,我正在尝试两天在图像上制作动画,而我的引擎正在考虑移动(这是一款游戏应用)。我在AsyncTask对象中执行chooseMove()方法,因为它是一个有点繁重的递归函数,可能需要一些时间,而且我还想在引擎思考时旋转沙漏图像。我试图以我知道的方式做到这一点:另一个AsyncTask,Android自己的动画类,处理程序等。但无论我做什么,似乎我无法使它发挥作用。如果我尝试同时执行两个线程,它只执行其中一个,并且同样的事情发生在android自己的动画类中。所以我试图使用进度对话只是为了看到我没有变得疯狂,并猜猜是什么..同样的问题!我在onPreExecute()中显示进度对话框,但doInBackgroun()永远不会完成!由于某种原因,进度对话框控制整个应用程序。我该怎么办?我虽然进度对话框是针对这种事情的。 THX!
编辑:这是我的异步任务类的代码。正如您所看到的,我在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;
}
答案 0 :(得分:0)
如果您想在AsyncTask
内执行任何与UI相关的操作,则需要调用AsyncTask
publishProgress方法。这将在主UI线程中调用onProgressUpdate
回调,因此您可以安全地在那里执行与UI相关的操作。
显然,onProgressUpdate
中的任何代码都无法阻止,因为您现在回到主UI线程中。但是,您可以更新状态栏,例如,等待下一次onProgressUpdate
回调再次更新之前。
答案 1 :(得分: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
}
}
}