【发布时间】:2016-01-19 22:38:51
【问题描述】:
我正在通过创建秒表来试验 Android 开发中的线程。我目前有一个非常基本的执行,似乎在模拟器上运行得很好,但是在我的手机上运行时效率不高(相当新的 Nexus 6,所以手机很好)。我的问题是,像秒表一样持续更新 UI 线程的最有效方法是什么?
我目前在更新 UI onProgressUpdate 的 AsyncTask 中运行它。我想 AsyncTask 不是最好的选择,但我也在我自己的 Runnable 中尝试过它,它运行得更糟。我阅读了有关 Handler 类的信息,但对如何使用它没有信心(或者知道它是否是答案)。下面是我创建和执行 AsyncTask 以及 AsyncTask 本身的地方。我应该注意到这是在一个片段中。
// Where the thread kicks off on click
private class StartTimer implements View.OnClickListener{
@Override
public void onClick(View v) {
// passes the stopWacth object and the view to update
clockThread = new HiitClock(clockTv, stopWatch);
clockThread.execute();
}
}
那么这是我扩展 AsyncTask 的类
public class HiitClock extends AsyncTask<String, Void, String> {
private final String LOG_TAG = HiitClock.class.getSimpleName();
private TextView clock;
private StopWatch stopWatch;
public HiitClock(TextView clock, StopWatch sw){
this.clock = clock;
this.clockSegment = clockSegment;
this.roundSegment = roundSegment;
this.stopWatch = sw;
}
@Override
protected String doInBackground(String... params) {
stopWatch.start();
while(stopWatch.getState() == 1 || stopWatch.getState() == 2){
publishProgress();
}
return "done";
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
clock.setText(convertTime());
}
@Override
protected void onPostExecute(String result) {
// end of timer
clock.setText(result);
}
/*
* helper method for converting the time
* */
private String convertTime(){
long milli = stopWatch.getTime();
long sec = milli / 1000 ;
long min = sec / 60;
sec = sec % 60;
milli = milli % 100;
return String.format("%02d:%02d:%02d", min, sec, milli);
}
}
-------更新---------
感谢您的回复。我已经尝试了所有建议,但在真实设备上的性能仍然很糟糕。我在下面创建了一个简单的示例。也许这个简单的版本将帮助某人了解我正在做的事情是阻止 UI 线程有效更新。它循环 100,000 次并使用处理程序来尝试更新 UI 线程。谢谢!
public class MainActivity extends Activity {
private RelativeLayout wrapper;
private TextView clockTv;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler();
wrapper = (RelativeLayout) findViewById(R.id.hitt_cardio_layout);
clockTv = (TextView) wrapper.findViewById(R.id.clock_text_view);
Button start = new Button(this);
start.setText("Start");
wrapper.addView(start);
start.setOnClickListener(new StartTimer());
}
private class StartTimer implements View.OnClickListener {
@Override
public void onClick(View v) {
new Thread(new Runner()).start();
}
}
private class Runner implements Runnable{
int i;
@Override
public void run() {
for(i = 0; i < 100000; i++){
handler.post(new Runnable() {
@Override
public void run() {
clockTv.setText("index: " + i);
}
});
}
}
}
}
【问题讨论】:
-
您正在使用 onProgressUpdate 来更新 UI 线程吗?那有什么问题?或者,您也可以使用 runOnUIThread 方法。
-
asynctasks 是出了名的低优先级,因此可能会被暂停以将处理器时间留给另一个线程。自调用
runOnUiThread效率更高,因为您根本不需要后台线程 -
感谢您的回复。不幸的是,似乎没有任何效果。我在上面添加了一个更简单的版本,可能有助于确定问题所在。
标签: java android multithreading android-asynctask