java - 我试图在屏幕上显示 CountDownTimer,但在 logcat 中得到 "Only one looper can be created per thread"

标签 java android multithreading

我是 Android 编程的初学者。我正在尝试在游戏中显示升级计时器,以显示升级将激活多长时间。在我的碰撞标志中,我调用 Looper.prepare 并按照 logcat 建议的方式启动我的线程类。我怎样才能让它在一个循环器上运行?

这是启动线程的代码 fragment 。

BigGapUpgrade.java

public boolean playerCollectUpgrade(Player player){
       if(Rect.intersects(rectangle, player.getRectangle())){
           Looper.prepare();
           bigGapUpgradeHandler.start();
       }

        return Rect.intersects(rectangle, player.getRectangle());
   }

这是我的线程类

BigGapUpgradeHandler.java

public class BigGapUpgradeHandler extends Thread {

    TimerTask scanTask;
    Timer timer = new Timer();

    @Override
    public void run() {
        Looper.prepare();
        scanTask = new TimerTask() {
            public void run() {

            }
        };

        timer.schedule(scanTask, 0, 4000);


        CountDownTimer countDownTimer = new CountDownTimer(4000, 100) {
            @Override
            public void onTick(long l) {
                Log.i(TAG, "onTick: ");
            }

            @Override
            public void onFinish() {
                timer.cancel();
                Log.i(TAG, "onFinish: ");
            }
        }.start();

        Looper.loop();
    }
}

运行后出现此错误

W/System.err: java.lang.RuntimeException: Only one Looper may be created per thread

--编辑

这是我想出的解决方案。

-- 解决方案

new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                CountDownTimer countDownTimer  = new CountDownTimer(5000,100) {
                    @Override
                    public void onTick(long millisUntilFinished) {

                        millis = millisUntilFinished/100;
                    }

                    @Override
                    public void onFinish() {

                    }
                }.start();
            }
        });

最佳答案

好的,所以你能做的就是使用 TimerTask。这会创建它自己的后台线程供您执行操作:

// This TimerTask Updates the UI so it needs a reference to the Activity.
static class PowerUpTimerTask extends TimerTask
{

  WeakReference<AppCompatActivity> mActivity;
  long                             mInterval;
  long                             mPeriod;

  public PowerUpTimerTask(AppCompatActivity activity, long period, long interval)
  {
    mActivity = new WeakReference<>(activity);
    mInterval = interval;
    mPeriod = period;
  }

  @Override
  public void run()
  {
    AppCompatActivity activity = mActivity.get();
    if (activity != null)
    {
      final TextView timerTextView = activity.findViewById(R.id.timerTextView);

      mPeriod -= mInterval;

      if (mPeriod > 0)
      {
        // Set time remaining
        activity.runOnUiThread(new Runnable()
        {
          @Override
          public void run()
          {
            timerTextView.setText(String.valueOf(mPeriod));
          }
        });

      }
      else
      {
        // Out of time...clear the Text and stop the timer task.
        activity.runOnUiThread(new Runnable()
        {
          @Override
          public void run()
          {
            timerTextView.setText("");
          }
        });

        Log.d(TAG, "Timer done. Canceling.");
        cancel();
      }
    }
    else
    {
      // Cancel this timer task since we don't have a reference to
      // the Activity any more.
      Log.d(TAG, "Lost reference to Activity. Canceling.");
      cancel();
    }
  }
}

然后您可以像这样启动计时器任务:

...
// Will count down from 10 by 1s.
mPowerUpTimerTask = new PowerUpTimerTask(this, powerUpTime, 1);

// Schedule for every second.
Timer t = new Timer();
t.scheduleAtFixedRate(mPowerUpTimerTask, 1000, 1000);
...

以下是此运行示例的链接:

https://github.com/didiergarcia/TimerTaskExample

关于java - 我试图在屏幕上显示 CountDownTimer,但在 logcat 中得到 "Only one looper can be created per thread",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56520210/

相关文章:

java - 如何在 Java 1.4 中将值结果集插入到 hashmap 中而不进行迭代?

java - 注册观察者与设置处理程序

java - 何时使用 OpenSession() 和 GetCurrentSession()

c# - 如何等待循环内的所有踏板完成运行

java - CompletableFuture没有得到执行。如果我使用ExecutorService池,则其工作正常,但不使用默认的forkJoin公共(public)池

java - 测量Java中每个对象使用的堆

android - IONIC添加android平台

java - Dalvik 的 ASM 或 CGLIB 模拟

android - 动态设置 View 的id

c++ - 什么时候调用继承的Constructor代码