【发布时间】: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