【问题标题】:Best practice for executing timed actions in Android在 Android 中执行定时操作的最佳实践
【发布时间】:2015-05-25 09:00:24
【问题描述】:

在我的代码的特定部分需要在一个定时空间中运行 3 个动作,现在我正在使用这种方法:

Handler mHander = new Handler();


public void startChainActions(){

// do first action
      mHandler.postDelayed(new Runnable() {
          @Override
          public void run() {

          //do action 2

                    mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {

                    //do action 3
                    }
                  }
                }, 1500);

              }
             }
            }, 5000);
           }


public void cleanResources(){

    mHandler.removeCallbacksAndMessages(null);
    mHandler==null
}

使用这种方法时,我经常在我的 logcat 上看到这条消息:

W/art﹕ Suspending all threads took: 12.272ms

这让我相信它会降低性能。 有没有更好的方法来计时?

【问题讨论】:

  • 您能解释一下为什么在方法的执行之间有必要“休眠”吗?
  • 您是否尝试过使用 CountdownTimer?
  • 原因是我需要在视图上使用 AnimationDrawble,使用两个有限时间的动画并让最后一个无限运行,所以第一个运行完成,第二个替换它,然后那个完成,第三个无限开始,我没有尝试使用 CountdownTimer,这样更好吗?有什么区别?
  • 我使用的是 AnimationDrawbles,而不是 Animations...

标签: android handler android-handler android-runtime


【解决方案1】:

首先你应该明白,在处理程序的情况下,你将在创建处理程序的同一线程中执行 Runnable。这意味着如果您在主线程中运行它,您将与任何用户UI交互共享硬件电源,并且不能保证执行开始的确切时间。

从正文回答您的问题 - 不,不会因为 2 个 postDelayed 调用而降低性能,但可能是因为您的行为。因此,您的日志消息与其他内容有关。

更新: 从标题中回答您的问题:如果您想运行延迟操作,那就是 - 这是在 Android 中执行此操作的正常方式,特别是如果您想在主/UI 线程中运行它。

【讨论】:

  • 这个动作链在空间中累积了很多次,(每秒最多可以累积 2 次)这还不足以解决性能问题吗?这个应用程序上没有用户交互,只有动画运行,其中大部分是 AnimationDrawbles
  • 动作链本身不会导致性能问题,动作会。
  • 谢谢,这有助于我理解一些事情,但是要回答问题的标题(以便我可以接受这是正确的答案),这是在安卓\java?
  • 如果您想运行延迟操作,那么可以 - 这是在 Android 中执行此操作的正常方式,特别是如果您想在主/UI 线程中运行它。希望它能回答你的问题。
【解决方案2】:

我们可以不使用SingleThreadExecutor,如下所示。

ExecutorService animationQueue = Executors.newSingleThreadExecutor();

animationQueue.submit( new Runnable() {
    public void run() {
        // action 1
        Thread.sleep(5000);
    }
});

animationQueue.submit( new Runnable() {
    public void run() {
        // action 2
        Thread.sleep(1500);
    }
});

animationQueue.submit( new Runnable() {
    public void run() {
        // action 3
    }
});

【讨论】:

  • 我可以,但是我希望在需要从中删除所有回调的情况下使用处理程序(并且可能有很多),并且处理程序为我提供了 removeAllCallBacksAndMessages(null) 的简单选项)。我只是想知道我在做什么是黑客还是正确的方法来做到这一点
  • @ZivKesten 对 Executors 的相同清理是使用 shutdownNow 方法完成的。
  • 您认为这是更好的方法吗?
  • @ZivKesten 在性能方面我不会说得更好。但就可读性而言,我会说得更清楚。
  • 感谢您的意见
猜你喜欢
  • 2015-04-14
  • 2023-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-13
  • 2017-08-15
相关资源
最近更新 更多