所以,我收到一个错误,我正在从错误的线程更新UI。这当然不是我的意图。我的案子很长,但我会尝试用代码片段做正义。我的最终目标是在一个单独的线程中运行一个昂贵的任务,并发布在路上和最后发生到我的listView的更新。
public class test extends Activity {
private ArrayAdapter<String> _mOutArrayAdapter;
private ListView _mOutView;
private EditText _mCmdEditText;
private Button _mRunButton;
private Interpreter _interpreter;
// Need handler for callbacks to the UI thread
public final Handler _mHandler = new Handler() {
public void handleMessage(Message msg) {
_mOutArrayAdapter.add(msg.getData().getString("text"));
};
};
// Create runnable for posting
final Runnable mUpdateResults = new Runnable() {
public void run() {
updateResultsInUi();
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
_interpreter = new Interpreter(true);
_mOutView = (ListView)findViewById(R.id.out);
_mCmdEditText = (EditText)findViewById(R.id.edit_command);
_mRunButton = (Button)findViewById(R.id.button_run);
_mOutArrayAdapter = new ArrayAdapter<String>(this, R.layout.message);
_mOutView.setAdapter(_mOutArrayAdapter);
_mOutArrayAdapter.clear();
_interpreter.setOutputAdapter(_mOutArrayAdapter);
Thread t = new Thread() {
public void run() {
_mResults = _interpreter.executeExpression("startup;",_mHandler);
_mHandler.post(mUpdateResults);
}
};
t.start();
);
然后在inpterpreter中我这样做:
public class Interpreter
{
private static Handler _mHandler;
public String executeExpression(String expression, Handler handler)
{
_mHandler = handler;
//Do a bunch of stuff that sometimes calls displayText from this class or from others
return answer;
}
public void displayText(String text)
{
Message msg = new Message();
Bundle bndl = new Bundle();
bndl.putString("text", text);
msg.setData(bndl);
_mHandler.dispatchMessage(msg);
}
}
最终答案的显示有效。并且dispatchMessage最终会触发handleMessage,但它会抛出一个错误,我无法从UI线程外部修改UI,我知道这是非法的。那么,我做错了什么?
谢谢!
答案 0 :(得分:3)
_mHandler.dispatchMessage(msg);
dispatchMessage()使Handler在当前线程上运行。 http://developer.android.com/reference/android/os/Handler.html
dispatchMessage(消息消息)
在此处理系统信息。
您应该使用_mHandler.sendMessage(msg);
它会将消息放入队列中,以便由声明处理程序的线程运行。
sendMessage(消息消息)
在当前时间之前的所有待处理消息之后,将消息推送到消息队列的末尾。
答案 1 :(得分:2)
我强烈建议您坚持使用AsyncTask
(或者如果您需要轮换/背景支持,请使用droid-fu版本之一),除非您知道自己正在进行什么。它将帮助您清晰地跟踪UI线程中正在运行的代码以及后台任务中的代码,并为您节省很多与自己处理Thread
和Handler
的混淆。可能导致。
答案 2 :(得分:1)
Handler的post方法需要参数中的Runnable对象,并调度该runnable块的执行。相反,您可以使用Handler.sendEmptyMessage()或Handler.sendMessage()向Handler发送消息。因此,请将您的代码更改为以下内容:
Thread t = new Thread() {
public void run() {
_mResults = _interpreter.executeExpression("startup;",_mHandler);
Message msg= _mHandler.obtainMessage();
msg.obj= _mResults;
_mHandler.sendMessage(msg);
}
};