11

我有一个服务,它每 0.1 秒向我的 Activity 发送一个 Intent。我用它来更新 Chronometer 的自定义实现。这里一切顺利。当我想更新 Activity 的 Fragment 内的 TableView 中的 14 个 TextView 时,问题就来了。这里的应用程序很慢。

我的 Activity 中从服务接收 Intent 的方法:

private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        long milis = intent.getLongExtra("milis",0);
        if( mFragment != null)
        mFragment.Update(milis);
    }
};

我更新 TextViews 的片段内的代码:

public void actualizarTiempoJuego(long milis){
    // Se recuperan los tiempos acumulados y se aumenta la cantidad pasada como parámetro
    for(int i=0;i<7;++i) {
        long mCurrentMilis1 = mVectorMilis1.get(i);
        long mCurrentMilis2 = mVectorMilis2.get(i);
        TextView1 t1 = mListaTitularLayoutLocal.get(i);
        TextView1 t2 = mListaTitularLayoutVisitante.get(i);
        t1.setText(String.value(milis + mCurrentMilis1));
        t2.setText(String.value(milis + mCurrentMilis2));
    }
}

我做错了什么,还是只是我试图在效率方面做一些非常复杂的事情?

4

6 回答 6

7

@Sherif 提出了一个很好的观点,即隐藏的 alpha 值会使您的应用程序陷入困境。根据您的平台,您可能还需要检查

<application android:hardwareAccelerated="true"... />

您可以研究的另一件可能有助于提高性能的事情是不会触发所有这些 Intent。一旦你开始触发意图,你就会让系统参与进来,并且取决于它们是如何得到解决的,它可能需要一些额外的时间。

对于这个问题,我喜欢使用Handlers。它们比意图更轻。您可能还想查看AsyncTask。这基本上就像一个线程,但也提供了在 UI 线程上运行的钩子,因此您可以执行后台操作和更新 UI,而无需发布可运行文件。

编辑:最后,您始终可以通过layoutopt工具运行您的布局。Romain Guy 亲自告诉我,如果你的画太慢,那么你就需要画得更少。只需从分析工具中查看屏幕截图(来自不太理想的视图树,但在最大值范围内)。您可以看到视图绘图占用了多少资源。如果您希望您的应用程序具有响应性,那么尽可能保持精简非常重要。 剖析视图绘图资源消耗

编辑:它不再被称为 layoutopt,它被称为lint。检查你的 ~/android-sdk/tools/

于 2012-06-19T20:52:02.610 回答
5

我曾经遇到过片段非常慢的情况。

我只是在预测您的片段具有某种 alpha,并且它是在“大量”活动上绘制的。

结论是,每次您设置 textview 的文本时,您的整个视图层次结构都会失效。

碎片似乎有这个缺陷。无论如何,使用一些布局而不是片段并检查它是否仍然“慢”。


setText补充:一个 wrap_content 文本视图会比一个 fill_parent 文本视图造成更多的延迟。

于 2012-06-19T20:44:37.953 回答
3

由于使用 TableLayout 和 TextView 进行布局管理,您可能会遇到速度变慢的情况。每次更新其中一个文本时,都必须进行大量的视图测量,以便将字符放在屏幕上的正确位置。你真的应该使用 Traceview 自己分析应用程序来找出答案。更多信息请访问:http: //developer.android.com/tools/debugging/debugging-tracing.html

对于相同类型的布局(片段> TableLayout> 多个TextViews),我遇到了完全相同的问题。测试您的 TableLayout/TextView 设置是否应该受到责备的一种方法是简单地将所有内容替换为单个 TextView。那可能会运行得很好。然后将您的 14 个视图放入 FrameLayout 或 RelativeLayout。即使它们都重叠,您仍然应该获得不错的性能,因为 TableLayout 视图测量的复杂性才是真正导致速度下降的原因。

于 2012-06-21T19:31:34.267 回答
0
  • You can try to declare vars outside the loop :

    public void actualizarTiempoJuego(long milis){
        // Se recuperan los tiempos acumulados y se 
        // aumenta la cantidad pasada como parámetro
    
        long mCurrentMilis1;
        long mCurrentMilis2;
        TextView1 t1;
        TextView1 t2;
    
        for(int i=0;i<7;++i) {
            mCurrentMilis1 = mVectorMilis1.get(i);
            mCurrentMilis2 = mVectorMilis2.get(i);
            t1 = mListaTitularLayoutLocal.get(i);
            t2 = mListaTitularLayoutVisitante.get(i);
            t1.setText(String.value(milis + mCurrentMilis1));
            t2.setText(String.value(milis + mCurrentMilis2));
        }
    }
    
  • And to setText() with mixed type, you can try setText("" + milis + mCurrentMilis2);

于 2012-06-26T15:47:48.657 回答
0

正如有人说您可以使用 HardwareAccelerated 但这不是一个很好的解决方案,如果您不能以其他方式解决它,您将浪费内存和 CPU。一个可能更安全的解决方案是减少 TextView 的数量。尝试将 14 减少到 7,它会快两倍。通常很难做到这一点,但如果你将对象放在一个策略位置,如果你用两行创建一个 TextView,那么一对 TextView 可以放在一起。并且不要忘记 findViewById 非常昂贵,如果您将使用视图对象,通常会一次性找到它并保存它的引用。

于 2012-06-25T23:58:06.310 回答
0

基准对于确定缓慢的实际来源总是有用的,但我很有信心表明发送 Intent 可能比更新 14 个 TextView 慢得多。每秒发送 10 个 Intent 表明您做错了 (TM)。这不是他们的目的。

我做错了什么,还是只是我试图在效率方面做一些非常复杂的事情?

每秒更新 14 个 TextView 本身并不复杂;您应该能够通过更合适的应用程序设计轻松实现这一目标。ASyncTaskHandler作为可能的工具浮现在脑海中,但如果不了解更多关于您正在尝试做什么的信息,就很难知道什么是最好的。

于 2012-06-26T00:20:33.013 回答