在我的片段中:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Handler uiHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
Bundle data = msg.getData();
String text = data.getString("event");
mTextView.setText(text);
}
};
server = new ServerClass(uiHandler);
在onCreateView()中,我设置了mTextView。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_main, container, false);
mTextView = (TextView) v.findViewById((R.id.event));
}
ServerClass的相关部分:
public class ServerClass {
private Handler mHandler;
public GameServer(Handler handler) {
mHandler = handler;
}
public void startServer(final int server_port) {
serverThread = new Thread(new Runnable() {
@Override
public void run() {
Socket socket = null;
Bundle data;
Message msg;
try {
serverSocket = new ServerSocket(server_port);
} catch (IOException e) {
e.printStackTrace();
return;
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
data = new Bundle();
data.putString("event", "new connection");
msg = new Message();
msg.setData(data);
mHandler.handleMessage(msg);
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
});
serverThread.start();
}
}
我的理解是,由于处理程序是在UI线程中创建的 - 在Fragment的onCreate()中 - 该处理程序中的handleMessage()也应该在UI线程上执行,但是没有发生。当我得到一个新连接时,我收到以下错误:
android.view.ViewRootImpl $ CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触及其视图。
在堆栈跟踪的其余部分结束后,指向handleMessage()中包含mTextView.setText(text);
的行作为原因。
我试过用getMainLooper设置处理程序,但没有帮助:
Handler mHandler = new Handler(Looper.getMainLooper()){
// ...
我也尝试在onCreateView()中创建处理程序,但仍然遇到同样的错误。
请告诉我,我错过了一些明显的东西,这让我把头发拉了出来。
答案 0 :(得分:1)
只有创建视图层次结构的原始线程才能触及它 视图。
因为使用来自非ui线程的Handler对象调用handleMessage
方法。
要从非ui线程发送消息,请使用Handler.sendMessage
方法:
Message msg = mHandler.obtainMessage();
data = new Bundle();
data.putString("event", "new connection");
msg.setData(data);
mHandler.sendMessage(msg);