为什么UI线程被阻止?

时间:2015-11-12 17:17:55

标签: java android multithreading ui-thread

在下面的代码中,我试图在单击按钮时运行一个线程。在按钮监听器中,我创建了一个新线程并运行它...但是在运行时,按下按钮时,按钮本身会冻结,应用程序不会响应,我会收到ANR对话框。此外,即使TexView

成功连接套接字
mtvStatus.setText("RFC-SOCKET CONNECTED");

什么也没有显示。

请让我知道为什么会这样。

按钮监听器

this.mbtnConnect.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            BluetoothSocket rfcSocket = mSPPCtrl.rfcConnect();
            if (rfcSocket.isConnected()) {
                mtvStatus.setText("RFC-SOCKET CONNECTED");

                Thread rx = new Thread(new RxRun(rfcSocket));
                rx.run();

            } else {
                mtvStatus.setText("RFC-SOCKET NOT CONNECTED");
            }

        }
    });

可运行的课程

private class RxRun implements Runnable {

    private BluetoothSocket mRFCSocket = null;
    private OutputStream mRFCOS = null;
    private InputStream mRFCIS = null;

    public RxRun(BluetoothSocket rfcSocket) {
        this.mRFCSocket = rfcSocket;

        try {
            this.mRFCOS = rfcSocket.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            this.mRFCIS = rfcSocket.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        try {
            this.mRFCOS.write(DIRON.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }

        while (this.mRFCSocket.isConnected()) {
            try {
                int readBytes = this.mRFCIS.read(new byte[5120]);
                Log.d(TAG, CSubTag.bullet("RxRun", "readBytes:" + readBytes));
                //mtvRx.setText(""+readBytes);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

2 个答案:

答案 0 :(得分:1)

  

...按下按钮时,按钮本身会冻结,应用程序不会响应,我会收到ANR对话框。此外,当套接字连接成功时,即使TexView也没有显示任何内容。

这是预期的,因为你实际上没有启动rx线程。这是正在发生的事情:

  1. mSPPCtrl已关联,
  2. mtvStatus的文字设置为"RFC-SOCKET CONNECTED",但您无法直观地看到它,因为
  3. run()实例的方法被称为手动,其中只要套接字连接,循环RxRun就可以持续。
  4. 所有上述内容都是在while (this.mRFCSocket.isConnected()) - 线程上调用的,这就是UI的原因。

    您不应手动拨打ANR。使用

    启动run()主题
    rx

    另外,我强烈建议移动线程内的所有rx.start(); 逻辑,并在连接成功/失败时通知rfcSocket - 线程。

    修改

    以下是我的评论中提到的一个选项。

    点击按钮

    启动UI主题
    rx

    将您的逻辑移到this.mbtnConnect.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new Thread(new RxRun(rfcSocket)).start(); } }); 方法中:

    run()

    一些可能有用的链接:

    1. Threads
    2. 上的Android文档
    3. 问题Android basics: running code in the UI thread
    4. Update UI from Thread
    5. 上的另一个SO帖子

答案 1 :(得分:1)

这里的错误非常简单 - 不要在Thread实例上使用run(),因为这实际上运行它在当前线程上的Runnable !使用start()它会正常工作: - )