0

好吧,我正在开发和通过蓝牙与另一个 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

我已经做到了,像我这样的新手可以做到最好的方式。它有效,但有时会崩溃,所以,我知道还有其他方法可以使它完美运行。

因此,这是对希望查看代码并帮助我的慷慨人士的请求。

当我们按下“读取值”按钮时,就会发生这种情况。必须注意的是,我使用一个可运行的处理程序在传输之间等待 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"
}

更新 - 添加问题

我想做的第一件事,但我不知道如何,当它进入 an 时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
...

所以这里是它崩溃的地方。

4

2 回答 2

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();
            }
        }
    });
}
于 2013-09-05T10:55:04.427 回答
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

于 2013-09-05T11:14:31.683 回答