我不明白我应该如何使用Inputstream和Handler。
我希望有人可以解释一下。我阅读了一些教程,我理解他们做了什么,但不了解他们是如何做到的。
以下是我不明白的例子:
public void run() {
int ret = 0;
byte[] buffer = new byte[16384];
int i;
while (true) { // read data
try {
ret = mInputStream.read(buffer);
} catch (IOException e) {
break;
}
i = 0;
while (i < ret) {
int len = ret - i;
if (len >= 1) {
Message m = Message.obtain(mHandler);
int value = (int)buffer[i];
// &squot;f&squot; is the flag, use for your own logic
// value is the value from the arduino
m.obj = new ValueMsg(&squot;f&squot;, value);
mHandler.sendMessage(m);
}
i += 1; // number of bytes sent from arduino
}
}
}
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
ValueMsg t = (ValueMsg) msg.obj;
// this is where you handle the data you sent. You get it by calling the getReading() function
mResponseField.setText("Flag: "+t.getFlag()+"; Reading: "+t.getReading()+"; Date: "+(new Date().toString()));
}
};
抱歉我的英文
答案 0 :(得分:2)
好的,我会尝试在问题和评论中回答您的问题。
首先:使用read()
在InputStream
上调用byte[]
会将字节读入缓冲区。
byte[] myBuffer = new byte[16384];
myInputStream.read(myBuffer);
此代码将读取inputstream
中的字节,并将其存储在名为byte[]
的{{1}}中。它不是从缓冲区读取的。
查看myBuffer
here或
从输入流中读取一些字节数并将它们存储到缓冲区数组b中。
<强>其次:强>
代码的作用(没有看到其余的代码)是它开始在后台线程上读取InputStream
。它每次都会读取一个字节:
inputstream
为了能够从后台线程更改视图,我们需要某种机制来在后台线程和UI线程之间建立桥梁,因为只有UI线程可以更改视图。
来了Handler: - )
引自ret = mInputStream.read(buffer);
文档:
[...]将要在不同于自己的线程上执行的操作排入队列。
在您的代码中,您因此“获取”与您的UI线程关联的当前Handler
:
Handler
之后,UI线程Message m = Message.obtain(mHandler); // Obtain the UI thread handler.
int value = (int)buffer[i]; // Read data.
m.obj = new ValueMsg(&squot;f&squot;, value); // Create a message to send to the UI thread handler.
mHandler.sendMessage(m); // Send the message to the UI thread handler.
收到Handler
方法中的消息:
handleMessage
并根据收到的消息采取相应行动,并在您选择的Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
ValueMsg t = (ValueMsg) msg.obj;
// this is where you handle the data you sent. You get it by calling the getReading() function
mResponseField.setText("Flag: "+t.getFlag()+"; Reading: "+t.getReading()+"; Date: "+(new Date().toString()));
}
中显示该消息。
TextView
在某种程度上是一个复杂的主题,但在很多地方都需要,当你开始使用多个线程时,大多数应用程序会在某些时候开始使用多个线程: - )
旁注
可以使用其他东西,但处理程序。
在您的while循环中,将Handlers
发送到用户界面message
,您可以使用名为Handler
的便捷方法替换Handler
代码,这样您的代码就可以了像这样的东西:
runOnUiThread(runnable)
请记住,上面的代码可能无法编译(我自己没试过......)。您必须使用while (i < ret) {
int len = ret - i;
if (len >= 1) {
runOnUiThread(new Runnable() {
int value = (int)buffer[i];
mResponseField.setText(String.valueOf(value));
});
}
i += 1; // number of bytes sent from arduino
}
或Activity
,因为Fragment
方法绑定到runOnUiThread
类。另外一些字段可能必须Activity
才能从final
方法中读取它们,但我希望你明白这一点: - )
希望这有帮助 - 否则让我知道,我会尝试详细说明: - )