在Fragment的onCreate()中创建的Android Handler不在UI线程上执行handleMessage()

时间:2015-04-03 02:24:31

标签: android multithreading callback handler

在我的片段中:

@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()中创建处理程序,但仍然遇到同样的错误。

请告诉我,我错过了一些明显的东西,这让我把头发拉了出来。

1 个答案:

答案 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);