【问题标题】:Android program crashes when writing to TextView in loopAndroid程序在循环写入TextView时崩溃
【发布时间】:2014-05-18 20:10:08
【问题描述】:

我正在尝试编写串行监视器。我遵循了 USB 输入的 Android 指南并使用 this post 作为参考。我得到了帖子中的代码,但我不想写日志。我想将输入写入 textView(或 UI 上的某些文本字段),但它只是崩溃了。我还希望能够从可编辑的文本字段中读取数据并通过 USB 连接发送数据。

我的设置与上面帖子中的设置非常相似,但具有不同的 run() 函数:

@Override
public void run() 
{
    mRunning = true;

    terminalWindow.append("Hello from thread.");
    while(mRunning)
    {
        byte[] recordIn = new byte[endpoint.getMaxPacketSize()];
        if(connection.bulkTransfer(endpoint, recordIn,recordIn.length, 1000)>0)
        {
            String infoIn = new String(recordIn);
            terminalWindow.append(infoIn.toString());
        }


    }
}

如何获取 infoIn 字符串以写入 TextView 终端窗口?我需要添加某种 sleep() 函数吗? (我试着在两次读取之间数到 1000 万次,但一旦返回,它也会崩溃)

-----------更新

感谢您的快速回复。我不得不稍微更改代码。为了连接到串行网桥,我必须断开我的 Android 设备与我的计算机的连接,这意味着我没有任何日志。但是,我认为如果没有调用 USB 库,我遇到的问题是一样的:

05-19 22:50:38.674: W/dalvikvm(7809):       threadid=11: thread exiting with uncaught exception (group=0x4159c7c0)
05-19 22:50:38.679: E/AndroidRuntime(7809): FATAL EXCEPTION: Thread-1617
05-19 22:50:38.679: E/AndroidRuntime(7809): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
05-19 22:50:38.679: E/AndroidRuntime(7809):     at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:5908)
05-19 22:50:38.679: E/AndroidRuntime(7809):     at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:869)
05-19 22:50:38.679: E/AndroidRuntime(7809):     at android.view.ViewGroup.invalidateChild(ViewGroup.java:4253)
05-19 22:50:38.679: E/AndroidRuntime(7809):     at android.view.View.invalidate(View.java:10546)
05-19 22:50:38.679: E/AndroidRuntime(7809):     at android.view.View.invalidate(View.java:10501)
05-19 22:50:38.679: E/AndroidRuntime(7809):     at android.widget.TextView.updateAfterEdit(TextView.java:7340)
05-19 22:50:38.679: E/AndroidRuntime(7809):     at android.widget.TextView.handleTextChanged(TextView.java:7363)
05-19 22:50:38.679: E/AndroidRuntime(7809):     at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:9076)
05-19 22:50:38.679: E/AndroidRuntime(7809):     at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:962)
05-19 22:50:38.679: E/AndroidRuntime(7809):     at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:496)
05-19 22:50:38.679: E/AndroidRuntime(7809):     at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:253)
05-19 22:50:38.679: E/AndroidRuntime(7809):     at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:30)
05-19 22:50:38.679: E/AndroidRuntime(7809):     at android.widget.TextView.append(TextView.java:3355)
05-19 22:50:38.679: E/AndroidRuntime(7809):     at android.widget.TextView.append(TextView.java:3342)
05-19 22:50:38.679: E/AndroidRuntime(7809):     at com.knolledge.cerealmonitor.MainActivity.run(MainActivity.java:119)
05-19 22:50:38.679: E/AndroidRuntime(7809):     at java.lang.Thread.run(Thread.java:841)

查看此日志以及 CommonsWare 提供的上下文,问题似乎确实是我有线程更新 UI。老实说,我什至不想使用新线程。但是,Android 文档建议这样做。那么最好的方法是什么?我应该让线程发送事件并让 UI 监听新读取的缓冲区吗? connection.bulkTransfer 只是永远轮询连接,还是有办法让它休眠并且只在中断后读取传入的数据包?

【问题讨论】:

  • 使用 LogCat 检查与您的崩溃相关的 Java 堆栈跟踪。很可能是因为上面的代码在后台线程上运行,你无法从后台线程更新 UI。
  • 感谢您的快速回复,@CommonsWare。我发布了日志。
  • "我是否应该让线程发送事件并让 UI 监听新读取的缓冲区?" -- 让后台线程从缓冲区中读取,并将新检索到的字节提供给 UI 层进行处理。您可以按照 Pardych 的建议使用 runOnUiThread()Handler 或事件总线(例如,greenrobot 的 EventBus)来执行此操作。 “connection.bulkTransfer 只是永远轮询连接,还是有办法让它休眠并且只在中断后读取传入的数据包?” -- 我没有使用过 USB API,所以我无法回答,抱歉。

标签: android multithreading usb textview


【解决方案1】:

使用runOnUiThread 追加terminalWindow 或使用AsyncTask 代替ThreadonProgressUpdate/publishProgress 追加文本 第二种方法更正确

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-06
    相关资源
    最近更新 更多