【问题标题】:Implementing a cyclic executive in android?在android中实现循环执行?
【发布时间】:2012-06-27 20:24:00
【问题描述】:

我正在编写一个 android 应用程序,我需要能够定期/连续地做某些事情。我来自 C/C++ 嵌入式固件背景,这种新奇的做事方式需要一些时间来适应。似乎Android中没有“主循环”之类的东西,一切都是事件驱动的......我也明白默认情况下你编写的所有代码都在GUI线程上运行,我可能应该创建一个新线程执行相当于“主循环”...

到目前为止,我所拥有的是 AsyncTask 类的实现,它的“doInBackground”方法包含一个无限循环(我的主循环),我创建了这个类的一个实例并在我的应用程序启动时立即运行它。我遇到的问题是这个线程和用户界面之间的交互......当我的主循环线程中发生某些事情并且我想更新 GUI 时,我知道我必须调用“publishProgress”,它在 GUI 线程上执行.这有一些问题,主要是我在这个“onProgressUpdate”方法中尝试做的许多事情都不起作用,或者没有在可预测的时间内发生。

我的问题,有没有更好的方法来完成我想做的事情?一般来说,当大多数人在他们的应用程序运行时想要定期和/或连续运行代码时,他们会做什么,这些代码必须及时与用户界面交互(我的意思是及时,零延迟)。

谢谢。

public class MainLoopThread extends AsyncTask<Void, Void, Void>
{
    @Override
    protected Void doInBackground(Void... arg0)
    {
        while(true)
        {
            //Do stuff

            //Update GUI
            publishProgress();
        }   
    }

    protected void onProgressUpdate(Void...voids)
    {
        //Update GUI
    }
}

【问题讨论】:

  • 您能澄清一下您要做什么吗?你的任务的执行周期是做什么的?为什么您的进度更新是 Void 类型,而不是某些实际包含更新 UI 的进度信息的数据类型?
  • 另外,“我的应用程序何时启动”是什么意思?对不起,如果我太自信了,但是由于您来自另一个平台,我怀疑您缺少一些 Android 基础知识。你不是说“当我的Activity 开始时”吗?
  • Nobu:我的应用程序将通过蓝牙与运行我也设计的硬实时操作系统的手持仪器进行通信……通信周期必须及时发生。此外,还有许多其他事情需要根据时间而不是用户输入发生,这更适合循环执行模型而不是事件驱动模型。
  • Arhimed:是也不是。我确实了解一个 android 应用程序包含一个或多个活动,而我的应用程序目前有 4 个不同的活动。但是,理想情况下,我试图制作的这个“主循环”将一直运行,无论哪个活动处于活动状态......所以我想用第一个活动开始循环,并且在活动时根本不中断它更改(可能有一两个不需要主循环运行的活动)
  • 我想一个更好的问题是如何在 Android 上制作游戏?大多数游戏不是事件驱动的,而是使用循环执行器......大多数游戏一直在进行,无论用户可能提供什么输入,在 Android 上是如何管理的?我真正的问题是,当活动开始时,我得到一个事件并使用 onCreate() 方法捕获它......当该方法结束时,代码“去”到哪里?无处?我需要一直执行代码,在一个循环中,代码流不能像看起来那样消失在无人区。

标签: android loops real-time executives


【解决方案1】:

目前尚不清楚您要做什么,但是让我说以这种方式使用AsyncTask 可能会产生负面影响。

AsyncTask 在内部使用线程池模式来运行来自doInBackground() 的内容。在 1.6 之前和从 3.0 开始的 Android OS 上,池大小仅为 1,这意味着一堆 AsyncTask 没有并行计算。有关此here 的更多详细信息。

因此,这可能会导致只有当前的AsyncTask 正在运行,而其他即使已启动也必须等到当前的运行完成。

根据您需要定期做的事情 Android 暴露:

  • AlarmManager
  • Handler - 它允许延迟或定期在 UI 线程上发布可运行的内容
  • Timer + Activity.runOnUiThread(Runnable action) 内部 TimerTask

更新:根据您的 cmets,您似乎需要一个 Service,它启动一个线程,该线程定期发送带有 UI 数据的广播。然后,您的 UI(Activity)注册广播接收器以捕获这些广播、提取数据并用于 UI 更新。

【讨论】:

  • 刚刚添加了更新部分
  • 感谢 Arhimed,我会调查 Service 类,如果它完成了我需要的工作,我会选择它作为接受的答案
  • @CHollman82:我知道从零开始实现服务 + 广播 + 接收器 + 意图 + 活动的组合可能有点棘手,特别是如果您是 Android 新手。通常采用 Android 需要时间,它很酷但同时也具有挑战性。
  • @CHollman82:由于我没有发布直接的解决方案,您可以简单地通过投票来表达您的感谢(但不接受它作为解决方案)。 :)
【解决方案2】:

所以你说 onProgessUpdate() 不起作用?这看起来很奇怪,因为它应该。 您拥有的另一个选择就是创建一个循环的线程。 诀窍是,如果你想更新 UI 线程,你必须调用 view.post() 并给它一个实际执行更新的 runnable。这里的想法是您必须在 UI 线程上安排更新,您不能只是接受它并说现在!

【讨论】:

  • 它可以工作,但它不能以可预测或可靠的方式工作......例如,我已经看到事情发生混乱,或者出现不可接受的延迟。
  • 是的。这可能是因为触摸事件的消费顺序。我们制作了一个新闻应用程序,它有一个列表视图,每个类别都有滚动行,使用起来真的很时髦。我们最终放弃了它,取而代之的是 ListViews 的 ViewPager。更好更流畅。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多