获取CalledFromWrongThreadException,只有创建视图层次结构的原始线程才能触及其视图。
在行handler2.sendMessage(msg);
上,用于从UI线程向下面的MulitThreaderSendback类发送短文本消息。
调用sendMessage(msg)在从onCreate方法内部调用它时可以正常工作,但是当我把它放在onClick侦听器中时,它会导致此异常崩溃。
如何避免此崩溃并能够从onclick侦听器调用它,以便我可以使用按钮按下来发送消息?
FROM LOGCAT:
E/AndroidRuntime(14366): FATAL EXCEPTION: Thread-1433
E/AndroidRuntime(14366): android.view.ViewRootImpl$CalledFromWrongThreadException:
Only the original thread that created a view hierarchy can touch its views.
E/AndroidRuntime(14366): android.view.ViewRootImpl.checkThread(ViewRootImpl.java:5432)
E/AndroidRuntime(14366): android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:970)
代码是:
public class MainActivity extends Activity implements Runnable {
TextView textViewOne;
TextView textViewTwo;
TextView textViewThree;
TextView textViewFour;
TextView textViewFive;
RelativeLayout relativeLayoutOne;
Handler handler;
Handler handler2;
Message msg;
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
relativeLayoutOne = (RelativeLayout) findViewById(R.id.relativeLayout1);
textViewOne = (TextView) findViewById(R.id.textView1);
textViewTwo = (TextView) findViewById(R.id.textView2);
textViewThree = (TextView) findViewById(R.id.textView3);
textViewFour = (TextView) findViewById(R.id.textView4);
textViewFour = (TextView) findViewById(R.id.textView5);
handler = new Handler();
// starting this class that implements Runnable
this.run();
// starting class that extends Thread
MultiThreader multiThreader = new MultiThreader(handler);
multiThreader.start();
// starting class that implements Runnable
MultiThreader2 multiThreader2 = new MultiThreader2(handler);
Thread thread = new Thread(multiThreader2);
thread.start();
MulitThreaderSendback multiSendBack = new MulitThreaderSendback();
Thread thread2 = new Thread(multiSendBack);
thread2.start();
synchronized (multiSendBack) {
while (handler2 == null) {
try {
multiSendBack.wait();
} catch (InterruptedException e) {
//Ignore and try again.
}
}
}
Bundle bundle = new Bundle();
String messageToSend = "message from UI class";
bundle.putString("message", messageToSend);
Random random = new Random();
int messageText = random.nextInt(30);
String putIt = String.valueOf(messageText);
bundle.putString("message", putIt);
msg = Message.obtain();
msg.setData(bundle);
// handler2.sendMessage(msg); // <-- WORKS OK HERE, NO CRASH
relativeLayoutOne.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
handler2.sendMessage(msg); // <-- FATAL ERROR: CalledFromWrongThreadException
}
});
} // end oncreate
public void setTextViewThree(String textToSet) {
textViewFour.setText(textToSet);
}
public void setTextViewFour(String textToSet) {
textViewFive.setText(textToSet);
}
// local class runnable
@Override
public void run() {
textViewOne.setText("message from local class runnable");
}
// multiThreader inner class
class MultiThreader extends Thread {
Handler handler;
public MultiThreader(Handler handler) {
this.handler = handler;
}
@Override
public void run() {
handler.post(new Runnable() {
@Override
public void run() {
textViewTwo.setText("message from multithreader class");
} // end inner run
});
} // end outer run
} // end MultiThreader inner class
// external multiThreader2 inner class
class MultiThreader2 implements Runnable {
Handler handler;
public MultiThreader2(Handler handler) {
this.handler = handler;
}
public void run() {
handler.post(new Runnable() {
@Override
public void run() {
textViewThree.setText("message from MultiThreader2 class");
} // end inner run
});
} // end outer run
} // end MultiThreader2 inner class
class MulitThreaderSendback implements Runnable {
int x = 0;
@Override
public void run() {
// TODO Auto-generated method stub
Looper.prepare();
synchronized(this) {
handler2 = new Handler() {
public void handleMessage(Message msg) {
Bundle bundle = msg.getData();
String receivedString = bundle.getString("message");
setTextViewThree("string received from UI thread: " + receivedString);
}
};
notifyAll();
}
Looper.loop();
} // end run method
} // end MultiThreaderSendback inner class
} // end outer class mainactivity
答案 0 :(得分:1)
您可以在此方法中嵌入行handler2.sendMessage(msg);
runOnUiThread(new Runnable() {
public void run() {
}
});
试试这个