【问题标题】:How to display 'thinking' image while Java method is running on Android app如何在 Android 应用程序上运行 Java 方法时显示“思考”图像
【发布时间】:2021-06-21 19:08:53
【问题描述】:

我正在编写一个用户可以与计算机对战的井字游戏应用程序。在其中一个困难中,我实现了一种算法(极小极大)来找到最佳移动,并且在第一步中,使用该算法进行移动的函数似乎需要相当长的时间才能运行。我想在计算机“思考”(执行功能)时在屏幕上弹出“思考”图像。我尝试在函数运行前后显示图像,但这似乎不起作用。

在我处理按钮按下的“onClick”方法中,这是应该显示思考图像、进行移动、然后在移动完成后使思考图像不可见的代码部分:

    displayThink(true);

    //if game not over, computer makes move
    makeMove(difficulty);

    displayThink(false);

displayThink 在哪里:

public void displayThink(boolean display)
{
    ImageView thinkingImage = (ImageView)findViewById(R.id.thinkingImage);


    if(display)
        thinkingImage.setVisibility(View.VISIBLE);
    else
        thinkingImage.setVisibility(View.INVISIBLE);

}

而 makeMove(difficulty) 是花费大量时间运行的函数。

编辑:这是在 onClick 函数中调用的 makeMove() 函数的完整上下文,它是用于处理活动中按钮按下的指定 onClick 方法:

 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);
    }

}

这是 xml 文件的 imageView 部分,用于处理我想在计算机“思考”时显示的图像。

 <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>

【问题讨论】:

  • 您的 makeMove() 代码是否在 UI 线程上运行?
  • 抱歉,我不确定这是什么意思。我查了 UI 线程,但我不这么认为,但你能详细说明一下吗?
  • 这意味着,如果您的长时间运行的任务在您的主线程或 UI 线程中运行,您将无法更新 UI,直到任务完成,否则您将崩溃。那么您能否展示一下您的 makeMove() 函数是如何被调用的?还有你的 imageview xml。
  • 好的,我会编辑问题。
  • 我看到您正在调用 UI 线程中的所有内容。这可能是您没有看到您的图像视图的原因。现在,您只需按照@javdromero 回答中描述的步骤进行操作

标签: java android image tic-tac-toe


【解决方案1】:

您可以使用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);
        }
    }

编辑:

这可以这样调用:

buttonX.setOnClickListener(new OnClickListener() {
    public void onClick(View v)
    {
        MakeMove makeMove = new MakeMove();
        makeMove.execute();
    } 
});

没有传递参数,因为它们是可选的。

【讨论】:

  • 谢谢!我将如何在我的 onClick 方法中实现这些功能?我会创建一个 MakeMove 对象,然后调用该对象上的函数吗?另外,我应该将什么作为参数传递给这些函数?
  • @yusefwilson 我对其进行了编辑以添加实现。
  • 感谢您的澄清 - 这个新的私有类如何访问函数 makeMove 和 displayThink?或者我会改变我当前的活动类来扩展 AsyncTask 吗?
  • 没必要,只要将该类添加到您的活动中,就好像它是另一种方法一样。
  • 再次感谢 - doInBackground 函数需要一个整数,因此我可以将该信息提供给在其中调用的 makeMove 函数,但我不知道如何使用您的实现.我会将其中一个 Void 更改为 Integer 吗?
猜你喜欢
  • 2020-01-01
  • 1970-01-01
  • 2014-07-31
  • 2011-02-25
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 2011-02-26
  • 1970-01-01
相关资源
最近更新 更多