好吧,我正在开发和应用程序,通过蓝牙与另一个PCB进行通信。它由3个搜索栏组成,用于调节PCB的3个参数值。
结构如下:
1. Send petition string for read the first value
2. Receive the first value
3. Send petition string for read the second value
4. Receive the second value
5. Send petition string for the third value
6. Receive the third value
我已经完成了,像我这样的新手可以做到最好的方式。它有效,但有时会崩溃,因此,我知道还有其他方法可以使它完美运作。
所以,这是对慷慨的人的要求,希望看看代码并帮助我。
当我们按下“读取值”按钮时,就会发生这种情况。必须注意的是,我使用runnable处理程序在transmisions之间等待1秒,让应用程序读取每个请求的答案:
public void receiveValues() {
/**Petition string that is sent to the PCB to request the variable's value*/
final String message_full1 = 2b e1 b4 e9 ff 1f b5; //variable 1
final String message_full2 = 2b e1 b8 e9 ff 1f b3; //variable 2
final String message_full3 = 2b e1 bc e9 ff 1f b1; //variable 3
final String message_full4 = 2b e0 bc f3 ff 1f 7c; //save request
final String message_full5 = 2b e0 be f3 ff 1f 7a; //save status
/*Send the first string to the PCB*/
byte[] send1 = message_full1.getBytes();
GlobalVar.mTransmission.write(send1);
/**Delay to wait until it receives the answer to the petition above*/
read1_handler.postDelayed(new Runnable() {
@Override
public void run() {
/**Read write confirmation after 1s = 1000ms*/
String inpuRead = "2b 00 ff fe c7 80"; //This string is what I receive as an answer via bluetooth
/**We check that the received string is not null, to avoid program crash*/
if (inpuRead != null) { //|| !inpuRead.equals("")) {
/*If it nos null, then we call the next function*/
int splitInt = splitReceivedString (inpuRead); //This function is declared below and extracts from the string , only the chars that we need.
receive1 = splitInt;
Toast.makeText(getApplicationContext(), "Loading values", Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(getApplicationContext(), "Communication error", Toast.LENGTH_SHORT).show();
}
}
}, 1000);
/**Delay to wait to send de second petition string*/
write2_handler.postDelayed(new Runnable() {
@Override
public void run() {
/**write message 2 after 1s = 1000ms*/
byte[] send2 = message_full2.getBytes();
GlobalVar.mTransmission.write(send2);
}
}, 2000);
/**Delay to wait until it receives the answer to the second petition string*/
read2_handler.postDelayed(new Runnable() {
@Override
public void run() {
/**Read write confirmation after 1s = 1000ms*/
String inpuRead = "2b 00 ff fe c7 80";
if (inpuRead != null) {
int splitInt = splitReceivedString (inpuRead);
receive2 = splitInt;
}
else {
Toast.makeText(getApplicationContext(), Communication error, Toast.LENGTH_SHORT).show();
}
}
}, 3000);
/**Delay to wait to send de third petition string*/
write3_handler.postDelayed(new Runnable() {
@Override
public void run() {
/**write message 3 after 1s = 1000ms*/
byte[] send3 = message_full3.getBytes();
GlobalVar.mTransmission.write(send3);
}
}, 4000);
/**Delay to wait until it receives the answer to the third petition string*/
read3_handler.postDelayed(new Runnable() {
@Override
public void run() {
/**Read write confirmation after 1s = 1000ms*/
String inpuRead = "2b 00 ff fe c7 80";
if (inpuRead != null) {
int splitInt = splitReceivedString (inpuRead);
receive3 = splitInt;
/**Set loaded values on seekbars*/
bar1.setProgress(receive1);
bar2.setProgress(receive2);
bar3.setProgress(receive3);
/**Message indicating the end of the transmission*/
Toast.makeText(getApplicationContext(), "Values loaded!", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(getApplicationContext(), "Communication error", Toast.LENGTH_SHORT).show();
}
}
}, 5000);
/**This makes a save request on the pCB*/
write4_handler.postDelayed(new Runnable() {
@Override
public void run() {
/**write message 3 after 1s = 1000ms*/
byte[] send4 = message_full4.getBytes();
GlobalVar.mTransmission.write(send4);
}
}, 6000);
/**This request a save statos on the PCB*/
write5_handler.postDelayed(new Runnable() {
@Override
public void run() {
/**write message 3 after 1s = 1000ms*/
byte[] send5 = message_full5.getBytes();
GlobalVar.mTransmission.write(send5);
/**Reset out string buffer to zero*/
GlobalVar.mOutStringBuffer.setLength(0);
}
}, 7000);
}
/**
* FUNCTION THAT SPLITS THE RECEIVED STRING TO GET THE DESIRED VALUES
*/
private int splitReceivedString (String s) { //For example, s = 2b 00 ff fe c7 80
StringTokenizer tokens = new StringTokenizer(s," ");
String one = tokens.nextToken();
String two = tokens.nextToken();
String three = tokens.nextToken();
String four = tokens.nextToken();
String five = tokens.nextToken();
String six = tokens.nextToken();
/**The next strings are whose got the seekbar's value*/ //f.e: "fffec780"
received_hexValue = three + four + five + six;
received_hexValue = received_hexValue.trim();
/**Conversion from hex to int to set the seekbar's values*/
int_value_receive = (int)Long.parseLong(received_hexValue, 16);
int_value_receive = -200000 - int_value_receive;
newIntValue = (int_value_receive * 100) / (200000 * (-1));
return newIntValue; //For this hex value, the int value to introduce in the seekbar is "60"
}
更新 - 问题已添加
我想做的第一件事,但我不知道怎么回事,当它进入if
时,如果这是真的,那么它必须继续执行代码,但如果它不是'如果是,那么它应该离开函数并停止执行代码。但是我这样做的方式,它继续执行。
我的意思是我有时会得到的崩溃是有时候,而不是以这种方式获得结构:
1. Send petition string for read the first value
2. Receive the first value
3. Send petition string for read the second value
4. Receive the second value
...
它的确如下:
1. Send petition string for read the first value
2. Send petition string for read the second value
3. Receive the first value
...
所以这就是它崩溃的地方。
答案 0 :(得分:1)
如果您希望轮流执行任务,则不需要所有7个额外的线程。只需将它们组合在一个Runnable
中,事情就会容易得多
我的意思是你所有的/**Delay to wait until...*/
评论都是错误的,你在上一次行动开始后等待1秒钟。因此,你只是在“发送请愿字符串以读取第二个值”之前没有完成“接收第一个值”,因为它花费的时间超过1秒。
示例:强>
您的代码已简化:
private Handler read1_handler = new Handler();
private Handler write2_handler = new Handler();
private Handler read2_handler = new Handler();
public void receiveValues() {
/**Delay to wait until it receives the answer to the petition above*/
read1_handler.postDelayed(new Runnable() {
@Override
public void run() {
String inpuRead = "2b 00 ff fe c7 80"; //This string is what I receive as an answer via bluetooth
if (inpuRead != null) { //|| !inpuRead.equals("")) {
int splitInt = splitReceivedString (inpuRead);
receive1 = splitInt;
Toast.makeText(getApplicationContext(), "Loading values", Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(getApplicationContext(), "Communication error", Toast.LENGTH_SHORT).show();
}
}
}, 1000);
/**Delay to wait to send de second petition string*/
write2_handler.postDelayed(new Runnable() {
@Override
public void run() {
byte[] send2 = message_full2.getBytes();
GlobalVar.mTransmission.write(send2);
}
}, 2000);
/**Delay to wait until it receives the answer to the second petition string*/
read2_handler.postDelayed(new Runnable() {
@Override
public void run() {
String inpuRead = "2b 00 ff fe c7 80";
if (inpuRead != null) {
int splitInt = splitReceivedString (inpuRead);
receive2 = splitInt;
}
else {
Toast.makeText(getApplicationContext(), Communication error, Toast.LENGTH_SHORT).show();
}
}
}, 3000);
}
具有正确执行顺序的代码:
private Handler handler = new Handler();
//TODO: don't call functions read1, write2 etc, call it something like "readSomeValue" where "SomeValue" is what you're trying to read
private void read1() throws IOException {
String inpuRead = "2b 00 ff fe c7 80"; //This string is what I receive as an answer via bluetooth
if (inpuRead != null) { //|| !inpuRead.equals("")) {
int splitInt = splitReceivedString (inpuRead);
receive1 = splitInt;
Toast.makeText(getApplicationContext(), "Loading values", Toast.LENGTH_LONG).show();
}
else {
throw new IOException("Error in read1");
}
}
private void write2() {
byte[] send2 = message_full2.getBytes();
GlobalVar.mTransmission.write(send2);
}
private void read2() throws IOException {
String inpuRead = "2b 00 ff fe c7 80";
if (inpuRead != null) {
int splitInt = splitReceivedString (inpuRead);
receive2 = splitInt;
}
else {
throw new IOException("Error in read2");
}
}
public void receiveValues() {
handler.post(new Runnable() {
@Override
public void run() {
try {
read1();
read2();
read3();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Communication error! " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
答案 1 :(得分:0)
对我来说,看起来你可以使用循环屏障,并且取决于一些魔法延迟是疯狂的。
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/CyclicBarrier.html
或者也许:
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/CountDownLatch.html