在我的申请中,有两件事情同时发生。活动中有一个时钟指针ImageView
,它不断被转动,用户也可以按下操作栏按钮。更新时钟的手会大大降低应用程序的性能,按钮需要几秒钟才能响应。我需要能够在另一个线程上运行时钟旋转,但到目前为止我无法做到这一点。
我尝试的第一件事是使用Handler
:
class MainActivity extends ActionBarActivity() {
Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
handler = new Handler();
startRotation();
}
private void startRotation() {
Runnable r = new Runnable() {
// do stuff to the UI here
};
handler.postDelayed(r, 100);
}
}
但是因为它在MainActivity
的线程上运行,所以它减慢了一切。
接下来,我使用了AsyncTask
,但您无法在不调用的情况下从AsyncTask更新UI:
MainActivity.this.runOnUiThread(new Runnable() {});
它仍然在主线程上运行并减慢了应用程序。
所以我的目标是:能够在一个线程上完全更新时钟的手,以便主线程仅用于用户交互,这样它们都能顺利运行。
谢谢
编辑:
旋转时钟分针的代码(每100毫秒更新一次):
Runnable r = new Runnable() {
ImageView minute_hand = (ImageView) findViewById(R.id.clock_hand_minute);
Calendar c = Calendar.getInstance();
float angle = 360f * ((float) c.get(Calendar.MINUTE) / 60f);
// minSdk is 11, so this works:
minute_hand.setRotation(angle);
};
答案 0 :(得分:1)
如果您正在执行此代码:
ImageView minute_hand = (ImageView) findViewById(R.id.clock_hand_minute);
Calendar c = Calendar.getInstance();
float angle = 360f * ((float) c.get(Calendar.MINUTE) / 60f);
minute_hand.setRotation(angle);
每100毫秒,然后我说它有点矫枉过正。
一般情况下,请注意,由于此代码每隔100毫秒在UI线程中运行,因此消耗的时间片将从UI响应用户交互所需的时间中删除。因此,它应该尽可能快!
首先,您应该将findViewById(R.id.clock_hand_minute)
代码移到runnable之外。在开始时调用它应该就足够了,因为视图不会改变。
其次,当一分钟过去时,分针移动6度,这是正确的。但是,您每100毫秒或每分钟600次这样做。这意味着视图正在针对每次(百分之一度)的非常小旋转进行更新,这些旋转可能几乎肉眼看不见,但在绘制方面耗时。
如果设置更新角度的最小阈值,可能会好得多。像
这样的东西if (angle - lastAngle > THRESHOLD)
minute_hand.setRotation(angle);