I’m coding a tic tac toe app in which the user can play against the computer. In one of the difficulties, I’ve implemented an algorithm (minimax) to find the best move, and on the first move, the function which uses this algorithm to make the move seems to take a noticeable time to run. I want to make a ‘thinking’ image pop up on the screen while the computer ‘thinks’ (executes the function). I’ve tried displaying an image before and after the function runs, but this doesn’t seem to work.
In my ‘onClick’ method which handles button pressing, this is the section of the code that is supposed to display the thinking image, make the move, and then make the thinking image invisible once the move is made:
displayThink(true); //if game not over, computer makes move makeMove(difficulty); displayThink(false);
where displayThink is:
public void displayThink(boolean display) { ImageView thinkingImage = (ImageView)findViewById(R.id.thinkingImage); if(display) thinkingImage.setVisibility(View.VISIBLE); else thinkingImage.setVisibility(View.INVISIBLE); }
and makeMove(difficulty) is the function that is taking the noticeable time to run.
EDIT: This is the full context of the makeMove() function which is called in the onClick function, which is the designated onClick method used to handle button presses in the activity:
public void onClick(View v) { //overwrite button Button b = (Button)v; b.setEnabled(false); b.setText(userString); //check result Pair<Boolean, String> p = checkEnd(); Log.d("msg","checking end: end = " + p.first); if(p.first) { Log.d("msg","launching result with string " + p.second); launchResult(p.second); } displayThink(true); //if game not over, computer makes move makeMove(difficulty); displayThink(false); //check result again p = checkEnd(); if(p.first) { Log.d("msg","launching result with string " + p.second); launchResult(p.second); } }
And this is the imageView part of the xml file that deals with the image I want to display while the computer is ‘thinking’.
<ImageView android:id="@+id/thinkingImage" android:layout_width="196dp" android:layout_height="264dp" android:layout_marginTop="160dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/thinking" /> </androidx.constraintlayout.widget.ConstraintLayout>
Advertisement
Answer
You could use an AsyncTask
private class MakeMove extends AsyncTask<Void, Void, Void> { @Override protected void onPreExecute() { // Runs on UI thread displayThink(true); } @Override protected Void doInBackground(Void... params) { // This doesn't run on the UI thread makemove(); } @Override protected void onPostExecute(Void args) { // Runs on UI thread displayThink(false); } }
EDIT:
This can be called like:
buttonX.setOnClickListener(new OnClickListener() { public void onClick(View v) { MakeMove makeMove = new MakeMove(); makeMove.execute(); } });
No arguments passed since they are optional.