我正在尝试在我的应用上显示一个计时器,其中一个线程计算经过的时间,一个处理程序来修改视图。
我知道Android不允许UI线程修改视图的其他线程,因此我使用Handler来执行此操作。
但它似乎没有效果,因为我仍然有“ android.view.ViewRoot $ CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触及其视图。”
我该怎么办?
(哦,如果这可能有帮助,代码如下)
package com.hangin.arround.emergency;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockActivity;
public class MainActivity extends SherlockActivity {
private static final String TAG = "MainActivity";
private TextView elapsedTime;
private Button startButton;
private Button stopButton;
private boolean shouldContinue = false;
private Handler mHandler;
private Runnable runnable;
private static final int MESSAGE_ELAPSED_TIME = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
// Creating the action bar, initializing my views and stuff
// Creating the Handler
mHandler = new Handler() {
@SuppressLint("SimpleDateFormat")
@Override
public void handleMessage(Message msg){
super.handleMessage(msg);
switch(msg.what) {
case MESSAGE_ELAPSED_TIME :
// Converting from milliseconds to a String
DateFormat formatter = new SimpleDateFormat("hh:mm:ss.SSS");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(msg.arg1);
String elapsedTimeString = formatter.format(calendar.getTime());
elapsedTime.setText(elapsedTimeString);
break;
default:
break;
}
}
};
// Creating the Runnable
runnable = new Runnable(){
@Override
public void run() {
int startTime, actualTime;
startTime = (int) System.currentTimeMillis();
Log.d(TAG, "startTime = " + startTime);
while(shouldContinue) {
// Calcul du temps écoulé
actualTime = (int)System.currentTimeMillis() - startTime;
Log.d(TAG, "actualTime = " + actualTime);
// Creating the message sent to the Handler
Message elapsedTimeMessage = new Message();
elapsedTimeMessage.what = MESSAGE_ELAPSED_TIME;
elapsedTimeMessage.arg1 = (int) actualTime;
// Sending the message
mHandler.handleMessage(elapsedTimeMessage);
}
}
};
// Adding the OnClickListeners on startButton and stopButton
startButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// Launching Thread
(new Thread(runnable)).start();
shouldContinue = true;
}
});
stopButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// Stopping the thread
shouldContinue = false;
}
});
}
}
答案 0 :(得分:1)
更改
Message elapsedTimeMessage = new Message();
elapsedTimeMessage.what = MESSAGE_ELAPSED_TIME;
elapsedTimeMessage.arg1 = (int) actualTime;
// Sending the message
mHandler.handleMessage(elapsedTimeMessage);
到
Message.obtain(mHandler, MESSAGE_ELAPSED_TIME, (int) actualTime, 0).sendToTarget();
从API文档中,似乎handleMessage
稍后在处理过程中调用,不应直接调用。
答案 1 :(得分:0)
为了在创建处理程序的线程上处理消息,您需要调用sendMessage
您应该使用mHandler.handleMessage(elapsedTimeMessage);
mHandler.sendMessage(elapsedTimeMessage);