安卓应用程序使用静态方法传输和绘制数据



我一直在问关于我的Android项目的问题,该项目不断实时绘制蓝牙数据。

基本上,我已经做的是通过拼凑一些开源代码Blueterm和OrientationSensorExample 来创建我的应用程序的第一个版本

有人建议我添加一个线程、一个处理程序、一个服务,或者使用Async Task或AIDL等。但我不知道如何使用其中的任何一个,希望能给出解释。

以下是我开始使用的Blueterm开源代码的描述(参见上面的链接)。Blueterm基本上是一个通过蓝牙进行通信的终端模拟器程序。它由几个活动组成,其中Blueterm是最重要的。它发现、配对并与支持SPP/RfComm的远程蓝牙设备连接。当连接时,我可以使用Blueterm来配置远程设备,方法是向它发送命令,打开采样,更改要采样的通道数(为一个通道),更改传入数据的格式(我喜欢逗号分隔的数据),等等

以下是我开始使用的OrientationSensorExample开源代码的描述(见上面的链接)。它基本上是AnroidPlot库的一个示例应用程序。OrientationSensor活动实现SensorEventListener。这包括覆盖onSenorChanged(),每当获取新的方向传感器数据时都会调用它,并重新绘制图形。

将这两个开源项目(Blueterm和OrientationSensorExample)拼凑成一个应用程序(Blueterm)后,下面描述整个应用程序(Blueterm)的工作方式。当我启动Blueterm时,整个屏幕都模仿一个漂亮的蓝色终端。在选项菜单中,我发现、配对、连接和配置远程蓝牙设备,如上所述。配置完远程设备后,我再次进入"选项菜单",选择"绘图数据",启动绘图活动。终端模拟器消失了,plot活动中出现了一个漂亮的滚动实时绘图。

据我所知,有一个后台线程调用update()方法,如下所示:

/**
 * Look for new input from the ptty, send it to the terminal emulator.
 */
private void update() {
    int bytesAvailable = mByteQueue.getBytesAvailable();
    int bytesToRead = Math.min(bytesAvailable, mReceiveBuffer.length);
    try {
        int bytesRead = mByteQueue.read(mReceiveBuffer, 0, bytesToRead);
        append(mReceiveBuffer, 0, bytesRead);
        //VTR use existing handler that calls update() to get data into plotting activity
        Plot.plotData(mReceiveBuffer, 0, bytesRead);
    } catch (InterruptedException e) {
        //VTR OMG their swallowing this exception
    }
}

在update()方法中,我发现调用Plot.protData()方法并将其传递给append()方法以绘制数据的相同日期很方便。注意:只有当plotData()是一个静态方法时,这才有效。没有人能够解释原因。

无论如何,plotData()是一个静态方法,下面是它和它的辅助方法现在的样子:

private static StringBuffer strData = new StringBuffer("");
public static void plotData(byte[] buffer, int base, int length) {
    Log.i("Entering: ", "plotData()");
    /*
    byte[] buffer = (byte[]) msg.obj;
    int base = msg.arg1;
    int length = msg.arg2;
    */
    for (int i = 0; i < length; i++) {
        byte b = buffer[base + i];
        try {
            if (true) {
                char printableB = (char) b;
                if (b < 32 || b > 126) {
                    printableB = ' ';
                }
                Log.w("Log_plotData", "'" + Character.toString(printableB)
                        + "' (" + Integer.toString(b) + ")");
                strData.append(Character.toString(printableB));
                if (b == 10)
                {
                    Log.i("End of line: ", "processBlueData()");
                    Log.i("strData", strData.toString());
                    splitData(strData);
                    strData = new StringBuffer("");
                }
            }
        } catch (Exception e) {
            Log.e("Log_plotData_exception", "Exception while processing character "
                    + Integer.toString(i) + " code "
                    + Integer.toString(b), e);
        }
    }
    Log.i("Leaving: ", "plotData()");
}
private static void splitData(StringBuffer strBuf) {
    String strDash = strBuf.toString().trim();
    String[] strDashSplit = strDash.split("-");
    for (int ndx = 0; ndx < strDashSplit.length; ndx++)
    {
        if (strDashSplit[ndx].length() > 0)
            Log.i("strDashSplit", ndx + ":" + strDashSplit[ndx]);
        String strComma = strDashSplit[ndx].trim();
        String[] strCommaSplit = strComma.split(",");
        for (int mdx = 0; mdx < strCommaSplit.length; mdx++)
        {
            if (strCommaSplit[mdx].length() > 0)
                Log.i("strCommaSplit", mdx + ":" + strCommaSplit[mdx]);
            if (mdx == 1)
            {
                int raw = Integer.parseInt(strCommaSplit[1],16);
                Log.i("raw", Integer.toString(raw));
                float rawFloat = raw;
                Log.i("rawFloat", Float.toString(rawFloat));
                float ratio = (float) (rawFloat/65535.0);
                Log.i("ratio", Float.toString(ratio));
                float voltage = (float) (5.0*ratio);
                Log.i("voltage", Float.toString(voltage));
                nowPlotData(voltage);
            }
        }
    }
}
public static void nowPlotData(float data) {
    // get rid the oldest sample in history:
    if (plotHistory.size() > HISTORY_SIZE) {
        plotHistory.removeFirst();
    }
    // add the latest history sample:
    plotHistory.addLast(data);
    // update the plot with the updated history Lists:
    plotHistorySeries.setModel(plotHistory, SimpleXYSeries.ArrayFormat.Y_VALS_ONLY);
    //VTR null pointer exception?
    if (plotHistoryPlot == null)
        Log.i("aprHistoryPlot", "null pointer exception");
    // redraw the Plots:
    plotHistoryPlot.redraw();
}

如果强烈建议plotData()不是一个静态方法,并且我应该做其他事情,请在这里以及如何解释。谢谢

这可能是一个更适合代码审查的问题,而不是在这里。也许你可以重新制定,把它张贴在那里,或者修剪很多,把它重新张贴在这里。

此外,为了回答:"有人建议我添加一个线程、一个处理程序、一个服务,或者使用异步任务或AIDL等。但我不知道如何使用这些,希望能给出解释。",最好的建议是将你链接到一本关于安卓的书,例如:http://commonsware.com/Android/。第35章和第36章涉及服务,而第20章涉及线程。你永远不会得到像这里那些章节那样完整的答案。

最新更新