我有一个服务,每隔0.1秒向我的活动发送一个意图。我用它来更新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);
}
};
Fragment中我更新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));
}
}
我做错了什么,或者仅仅是因为我想在效率方面做一些非常复杂的事情?
答案 0 :(得分:7)
@Sherif提出了一个关于隐藏的alpha值的好点,这会让你的应用程序陷入困境。 您可能还需要检查
,具体取决于您的平台<application android:hardwareAccelerated="true"... />
你可以研究的另一件事可能有助于提高性能并不能解决所有这些意图。一旦你开始触发意图,你就会得到系统,并且根据它们如何得到解决,可能需要一些额外的时间。
对于这个问题,我喜欢使用Handlers。它们比意图更轻。 您可能还想查看AsyncTask。这基本上就像一个线程,但也提供了在UI线程上运行的钩子,因此您可以执行后台操作并更新UI而无需发布runnables。
编辑:最后,您始终可以通过layoutopt工具运行布局。 Romain Guy亲自告诉我,如果你的绘图太慢,那么你需要画得更少。只需从分析工具中查看截图(来自不太理想的视图树,但在最大范围内)。您可以看到视图绘制占用了多少资源。如果您希望应用程序具有响应能力,那么尽可能保持精简非常重要。
编辑:它不再被称为layoutopt,它被称为lint。检查你的〜/ android-sdk / tools /
答案 1 :(得分:5)
我曾经遇到片段非常慢的情况。
我只是预测你的片段有某种类型的alpha并且是在“重”活动上绘制的。
结论是,每次设置textview的文本时,整个视图层次结构都将失效。
似乎碎片有这个缺陷。无论如何,使用一些布局而不是片段,并检查它是否仍然“慢”。
附加:在setText
之后,wrap_content textview将导致比fill_parent textview更多的延迟。
答案 2 :(得分:3)
由于使用TableLayout和TextView进行布局管理,您可能会遇到速度下降。每次更新其中一个文本时,都必须进行大量的视图测量,以便将字符放在屏幕上的正确位置。您应该使用Traceview自行分析应用程序以找出答案。有关更多信息,请访问:http://developer.android.com/tools/debugging/debugging-tracing.html
我遇到了与您使用相同类型的布局(Fragment&gt; TableLayout&gt; Multiple TextViews)完全相同的问题。测试TableLayout / TextView设置是否应该受到指责的一种方法就是用一个TextView替换所有这些。这可能会运行得很好。然后将您的14个视图放入FrameLayout或RelativeLayout。即使它们都重叠,你仍应该获得不错的性能,因为TableLayout视图测量的复杂性确实会导致速度减慢。
答案 3 :(得分:0)
正如有人说你可以使用HardwareAccelerated但这不是一个很好的解决方案,如果你不能以不同的方式解决它,你会浪费ram和cpu。一个解决方案可能更安全的是减少TextView的数量。尽量减少14到7,它会快两倍。通常很难做到,但是如果你把对象放在一个策略位置,那么如果你用两行创建一个TextView,那么一对TextView就可以在一起。并且不要忘记findViewById是如此昂贵,如果您将使用视图对象经常找到它并保持其参考。
答案 4 :(得分:0)
基准测试总是很有用,可以确定缓慢实际来自何处,但我觉得相信发送Intent可能比更新14个TextView要慢得多。每秒发送10个意图表明你正在做错误(TM)。这不是他们想要的。
我做错了什么,或者仅仅是因为我想在效率方面做一些非常复杂的事情?
每秒更新14个TextView本身并不复杂;您应该能够通过更合适的应用程序设计轻松实现这一目标。我会想到ASyncTask或Handler作为可能的工具,但如果不了解更多关于您正在尝试做什么的事情,很难知道什么是最好的。
答案 5 :(得分:0)
您可以尝试在循环外声明变量:
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));
}
}
对于混合类型的setText()
,您可以尝试setText("" + milis + mCurrentMilis2);