Android 延迟向 OBD 发送 ArrayList 命令
Android send ArrayList commands with delay to OBD
我需要延迟发送命令列表到 OBD 端口,因为 ELM327 无法同时管理所有命令...
我正在尝试使用此代码但无法正常工作
public void repeatCommand(){
for (final String command : commandArray){
Log.d(TAG, "Giro for");
final Handler handlerTimed = new Handler();
handlerTimed.postDelayed(new Runnable() {
@Override
public void run() {
//Do something after 100ms
sendMessage(command);
}
}, 1000);
}
/*String message = "010C\r";
sendMessage(message);*/
}
它只在 1 秒后发送第一个命令,但其他命令都没有。
我如何发送所有延迟的命令让写入来管理发送到 OBD 的所有命令?
好的,我使用建议的方法发送第一个命令并等待响应....收到响应后,发送下一条消息。
private synchronized void manage(BluetoothSocket socket, BluetoothDevice
device) {
Log.d(TAG, "connected, Socket Type:");
// Cancel the thread that completed the connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
// Cancel any thread currently managing connections
if (mManageThread != null) {
mManageThread.cancel();
mManageThread = null;
}
// Start the thread to manage the connection and perform transmissions
mManageThread = new ManageDataThread(socket);
mManageThread.start();
// Send the name of the connected device back to the UI Activity
Message msg = mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(Constants.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
// Update UI title
updateUserInterfaceTitle();
}
这里是管理连接的Thread..
public class ManageDataThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private boolean wait_response = false;
public ManageDataThread(BluetoothSocket socket) {
Log.d(TAG, "create ManageDataThread: ");
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
mState = STATE_CONNECTED;
}
public void run() {
while(true) {
for (final String command : commandArray) {
byte[] send = command.getBytes();
write(send);
//mState = STATE_WAIT_RESPONSE;
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
while (wait_response) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
//TODO devo gestire l'arrivo di bytes
ObdCommand obc = new ObdCommand();
obc.readResult(mmInStream);
formattedMessage = obc.getResult();
//buffer = (byte) obc.getBuffer();
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, formattedMessage)
.sendToTarget();
wait_response = false;
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
break;
}
}
}
}
}
它有点不完美,但现在可以了....
我将打开一个新的 post 来停止它并更新命令数组列表,因为如果我更改命令列表,循环会保留旧数组列表,所以我需要通知线程数组列表已更改
编辑
不要在线程内部使用 while(true) ,最好使用变量设置为 True e 当需要停止线程时将变量设置为 false,否则在停止线程时会出现问题....
需要考虑的一件事是,当您创建一个处理程序并且不为其提供循环器时,它将使用它的循环器当前线程。
所以我最好的猜测是,因为我们没有你的代码,你实际上 运行 在一个不是主线程的线程中执行它。确保你的线程不会在途中的某个地方被杀死并且它应该可以工作。
此外,一些编码技巧:
首先,我必须说,将处理程序设置在循环 外部 会更有效。
这样你就不会浪费内存在每次迭代中创建处理程序。
所以它应该看起来像这样:
public void repeatCommand()
{
final Handler handlerTimed = new Handler();
for (final String command : commandArray){
Log.d(TAG, "Giro for");
handlerTimed.postDelayed(new Runnable() {
@Override
public void run() {
//Do something after 100ms
sendMessage(command);
}
}, 1000);
}
}
其次,我强烈建议您设置 class 的常量,例如 1000 值。
使用 OBD2(一种串行协议)的正确方法是实现类似于命令队列的东西,其中包含特定于命令的回调,将响应传递给您向其请求的命令。命令队列应该工作在后台线程,操作队列和监听串口。甚至不要以延迟或类似方法开始。
我需要延迟发送命令列表到 OBD 端口,因为 ELM327 无法同时管理所有命令...
我正在尝试使用此代码但无法正常工作
public void repeatCommand(){
for (final String command : commandArray){
Log.d(TAG, "Giro for");
final Handler handlerTimed = new Handler();
handlerTimed.postDelayed(new Runnable() {
@Override
public void run() {
//Do something after 100ms
sendMessage(command);
}
}, 1000);
}
/*String message = "010C\r";
sendMessage(message);*/
}
它只在 1 秒后发送第一个命令,但其他命令都没有。 我如何发送所有延迟的命令让写入来管理发送到 OBD 的所有命令?
好的,我使用建议的方法发送第一个命令并等待响应....收到响应后,发送下一条消息。
private synchronized void manage(BluetoothSocket socket, BluetoothDevice
device) {
Log.d(TAG, "connected, Socket Type:");
// Cancel the thread that completed the connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
// Cancel any thread currently managing connections
if (mManageThread != null) {
mManageThread.cancel();
mManageThread = null;
}
// Start the thread to manage the connection and perform transmissions
mManageThread = new ManageDataThread(socket);
mManageThread.start();
// Send the name of the connected device back to the UI Activity
Message msg = mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(Constants.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
// Update UI title
updateUserInterfaceTitle();
}
这里是管理连接的Thread..
public class ManageDataThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private boolean wait_response = false;
public ManageDataThread(BluetoothSocket socket) {
Log.d(TAG, "create ManageDataThread: ");
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
mState = STATE_CONNECTED;
}
public void run() {
while(true) {
for (final String command : commandArray) {
byte[] send = command.getBytes();
write(send);
//mState = STATE_WAIT_RESPONSE;
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
while (wait_response) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
//TODO devo gestire l'arrivo di bytes
ObdCommand obc = new ObdCommand();
obc.readResult(mmInStream);
formattedMessage = obc.getResult();
//buffer = (byte) obc.getBuffer();
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, formattedMessage)
.sendToTarget();
wait_response = false;
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
break;
}
}
}
}
}
它有点不完美,但现在可以了.... 我将打开一个新的 post 来停止它并更新命令数组列表,因为如果我更改命令列表,循环会保留旧数组列表,所以我需要通知线程数组列表已更改
编辑
不要在线程内部使用 while(true) ,最好使用变量设置为 True e 当需要停止线程时将变量设置为 false,否则在停止线程时会出现问题....
需要考虑的一件事是,当您创建一个处理程序并且不为其提供循环器时,它将使用它的循环器当前线程。
所以我最好的猜测是,因为我们没有你的代码,你实际上 运行 在一个不是主线程的线程中执行它。确保你的线程不会在途中的某个地方被杀死并且它应该可以工作。
此外,一些编码技巧:
首先,我必须说,将处理程序设置在循环 外部 会更有效。
这样你就不会浪费内存在每次迭代中创建处理程序。
所以它应该看起来像这样:
public void repeatCommand()
{
final Handler handlerTimed = new Handler();
for (final String command : commandArray){
Log.d(TAG, "Giro for");
handlerTimed.postDelayed(new Runnable() {
@Override
public void run() {
//Do something after 100ms
sendMessage(command);
}
}, 1000);
}
}
其次,我强烈建议您设置 class 的常量,例如 1000 值。
使用 OBD2(一种串行协议)的正确方法是实现类似于命令队列的东西,其中包含特定于命令的回调,将响应传递给您向其请求的命令。命令队列应该工作在后台线程,操作队列和监听串口。甚至不要以延迟或类似方法开始。