Android应用使用静态方法传输和绘制数据

时间:2011-06-06 00:04:07

标签: android multithreading static thread-safety

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

基本上我已经完成的工作是通过拼凑一些开源代码BluetermOrientationSensorExample

来创建我的应用的第一个版本

有人建议我添加一个线程,一个处理程序,一个服务,或使用异步任务,或AIDL等。但我不知道如何使用这些,并希望得到解释。

以下是我开始使用的Blueterm开源代码的说明(参见上面的链接)。 Blueterm基本上是一个通过蓝牙进行通信的终端仿真器程序。它由几项活动组成,Blueterm是最重要的。它发现,配对并连接支持SPP / RfComm的远程蓝牙设备。连接后,我可以使用Blueterm配置远程设备,通过发送命令打开采样,更改要采样的通道数(到一个通道),更改为传入数据的格式(我喜欢逗号分隔数据)等< / p>

以下是我开始使用的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.plotData()方法并将其传递给传递给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()不是静态方法,我应该做其他事情,请在这里解释一下。谢谢!

1 个答案:

答案 0 :(得分:2)

这可能是一个更适合Code Review的问题,而不是在这里。也许你可以重新拟定在那里发布它,或者修改它以便在这里重新发布它。

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