Skip to content
Advertisement

How to display ‘thinking’ image while Java method is running on Android app

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.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement