每秒更新多个UI元素的性能问题

时间:2012-03-01 03:08:33

标签: android performance user-interface timer handler

编辑:我在下面发布了我的解决方案,(基本上,由于某些原因,ListViews非常慢),如果我能澄清为什么ListView如此糟糕,我会尝试进一步更新它在这种情况下。

目的:

获取7个ListView对象,显示7个独立设置的时钟/定时器,每秒更新/滴答。这些时钟只是字符串,显示计算的经过时间(SystemClock.ElapsedRealTime() - 存储对象实例化时的ElapsedRealTime()。)

问题:

基本上,在这7个时钟的8分钟之后 - 我的程序基本没用..所提供的信息不准确,用户界面几乎没有反应等等。以下是针对物理秒表基准测试的一些结果:

  • 在04:00,时钟滑动1秒,每4秒更新一次。
  • 在06:00,时钟滑动3秒,每5秒更新一次。
  • 在08:00,时钟滑动6-7秒,每6秒更新一次。
  • 在16:00,时钟正在下滑7秒,并且每10秒更新一次。

到目前为止我有什么:

我有一个自定义类ActivityTimer,其存储长度表示首次实例化每个ActivityTimer时的SystemClock.ElapsedRealTime()。通过单击按钮7次,我实例化其中的7个,每个都添加到ArrayList

我有一个复合视图ActivityTimerControl,它在实例化时传递一个ActivityTimer,然后在UI元素中显示我的ActivityTimer的数据元素(例如滴答时钟。)我的ArrayAdapter处理这个实例并且工作正常。根据{{​​3}}我在这个ActivityControl中有一个_Handler,在构建ActvityControl时会发布这个:

private Runnable _timerUpdateTask = new Runnable() 
{
    public void run() 
    {
        final long start = _ActivityTimer.getStartTime();
        long millis = SystemClock.elapsedRealtime() - start;
        int seconds = (int) (millis / 1000);
        int minutes = seconds / 60;
        seconds     = seconds % 60;
        if (seconds < 10) 
        {
            _tglActivityPauseButton.setTextOn(""+minutes+":0"+seconds);
        } 
        else 
        {
            _tglActivityPauseButton.setTextOn("" + minutes + ":" + seconds);            
        }
        _tglActivityPauseButton.setChecked(true);
        _timerUpdateHandler.postDelayed(this, 1000);
        }
};

除了我所描述的,我的项目还没有做任何事情,因为到目前为止我一直坚持这个基本问题。所以我没有发布任何其他代码,因为我不认为它的相关性超出了我上面给出的摘要 - 但如果有人觉得项目的其他部分是相关的,请告诉我,我会发布详细的它的代码。我将我的最终字符串呈现在ToggleButton的SetTextOn()中,但测试表明这不是一个重要因素 - 无论我是设置普通TextView的文本,还是什么,没有无论我尝试过什么,我的结果总是大致相同,每个时钟都有明显的延迟,最终用户界面完全没有反应。

我的理解是Handler应该是在一致且频繁的基础上更新UI元素的最有效方式,替换java.util.Timer,但尽管如此,我的代码开始变慢,只是变得越来越糟我让它运行。

即使将postDelay增加到5000ms,仍然会出现同样的问题,并且应用程序在49分钟后仍然强制关闭。因为我认为这个测试会延长时间直到强制关闭5,如果不完全修复它(不利于我想要的功能),我怀疑某些东西不能正确地与处理程序一起回收或者其他一些组件。

我的问题:

  • 我怀疑我的问题在于有7个对象(ActivityControls),每个对象都有自己的处理程序,不断循环显示相应时间的更新。有没有人有经验说这是否会是这种情况?
  • 我有没有办法让处理程序调用ListView中的每个ActivityControl来更新它的时间?
  • 是否向处理程序发送消息会留下一些不会自动处理的内存跟踪,或者可能会因强制处置而受益?
  • 是否有其他人对在多个对象上运行常量UI更新的最有效方法有其他想法?

2 个答案:

答案 0 :(得分:0)

你推迟1秒

_timerUpdateHandler.postDelayed(this,1000);

您无法随时运行代码。

答案 1 :(得分:0)

呃..你不知道吗...这对我的处理程序或其他任何类似问题都不是问题。这或者是ListView的低效率,或者是在ArrayAdapter中发生的一些funkiness(我使用的那个就像它一样简单。)我创建了一个沙箱项目(下面)并将我的7个ActivityTimers实例化为一个ArrayList,然后使用每个对象迭代遍历该数组,以实例化一个ActivityControl,该ActivityControl从数组传递了该ActivityTimer的副本。我以前做的所有事情,但用ScrollView中包含的LinearLayout替换ListView。 16分钟后,我有大约每一秒钟就有7个ActivityControl,并保持准确的时间。即使在30分钟后,也没有出现任何轻微的问题(应该是这样!)这就是我的所作所为:

public class Sandbox_Experiments extends Activity {
ArrayList<com.maxx233.Sandbox.ActivityTimer> _ActivityTimers = null;

@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    _ActivityTimers = new ArrayList<com.maxx233.Sandbox.ActivityTimer>();
    View myLayout =  findViewById(R.id.Info);

    com.maxx233.Sandbox.ActivityTimer act1 = new com.maxx233.Sandbox.ActivityTimer();
    com.maxx233.Sandbox.ActivityTimer act2 = new com.maxx233.Sandbox.ActivityTimer();
    com.maxx233.Sandbox.ActivityTimer act3 = new com.maxx233.Sandbox.ActivityTimer();
    com.maxx233.Sandbox.ActivityTimer act4 = new com.maxx233.Sandbox.ActivityTimer();
    com.maxx233.Sandbox.ActivityTimer act5 = new com.maxx233.Sandbox.ActivityTimer();
    com.maxx233.Sandbox.ActivityTimer act6 = new com.maxx233.Sandbox.ActivityTimer();
    com.maxx233.Sandbox.ActivityTimer act7 = new com.maxx233.Sandbox.ActivityTimer();


    _ActivityTimers.add(act1);
    __ActivityTimers.add(act2);
    __ActivityTimers.add(act3);
    __ActivityTimers.add(act4);
    __ActivityTimers.add(act5);
    __ActivityTimers.add(act6);
    __ActivityTimers.add(act7);


    for (int i = 0; i < __ActivityTimers.size(); i++)
    {
        ActivityControl ac = new ActivityControl(this, (com.maxx233.Sandbox.ActivityTimer)__ActivityTimers.get(i));
        ac.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));
        ((LinearLayout)myLayout).addView(ac);
    }
}

}

因此,我将努力弄清楚在方程式中导致这样一个问题的具体问题是什么,然后我会更新这个线程以防其他人遇到类似的问题。除非那里的其他人碰巧已经知道为什么ListView会每秒更新一些对象,因此资源密集程度更高?