java - 快速处理数据

标签 java android multithreading performance android-progressbar

我的应用程序每 80 毫秒获取一次数据(我今天问了我的老板,他说 80 毫秒没问题,但完美的是 2 毫秒 - 20 毫秒,所以比我想象的还要快)。我需要处理传入的消息,所以我尝试使用 if 子句处理它们,每次 if 子句为真时,TextView

中都会有一个新文本集

像那样:

if (data.equalsIgnoreCase(test)) {
    TextView tv = (TextView) findViewById(R.id.textview);
    tv.setText(" 30 % ");
}

问题是,数据传入的速度如此之快,而 if 子句似乎不够“快”以处理它。

TextView 仅在我停止传输消息时发生变化,然后在短暂的“等待”之后 TextView 发生变化。

有什么东西可以让它更“实时”吗?

我没有通过谷歌找到有用的东西,我的编程技能非常薄弱,只是为了防止更多的反对票

编辑:

我现在发现,我必须检查 768 个不同的值(所有十六进制代码)。所以会有 768 个 if 语句。那肯定会降低速度。

问题是,我不能“等待”先执行 if 语句然后获取下一条消息。

消息刚刚流入。

我刚刚更新了我的代码,现在使用 ProgressBar 而不是 TextView

if (data.equalsIgnoreCase(TEST)){
    mProgressBar.setProgress(0);
}

EDIT2: 添加了线程代码

class RxThread extends Thread { 
    private static final String TEST =  "0 0 0 0 0 40 0 0 ";
private static final String TEST2 = "0 1 0 0 0 41 0 0 ";
private static final String TEST3 = "2 bb 0 0 2 fb 0 0 ";
private static final String TEST4 = "2 bd 0 0 2 fd 0 0 ";
private static final String TEST5 = "2 be 0 0 2 fe 0 0 ";

Handler myHandler = new Handler();

final Runnable r = new Runnable() {
    public void run() {

        demoRxMsg = new MessageStructure();

        while (rxChannel.receiveMessage(demoRxMsg) == ReturnCode.SUCCESS) {

            String data = "";
            String format = "";

            rxChannel.receiveMessage(demoRxMsg);

            if (demoRxMsg.frameFormat == API_ADK.STANDARD_FRAME) {
                format = "SFF";
            } else {
                format = "EFF";
            }
            for (byte i = 0; i < demoRxMsg.dataLength; i++) {
                data = data + Integer.toHexString(demoRxMsg.data[i]) + " ";
            }

            if (data.equalsIgnoreCase(TEST)){
                mProgressBar.setProgress(0);
            } else if (data.equalsIgnoreCase(TEST2)) {
                mProgressBar.setProgress(1);
            } else if (data.equalsIgnoreCase(TEST3)) {
                mProgressBar.setProgress(94);
            } else if (data.equalsIgnoreCase(TEST4)) {
                mProgressBar.setProgress(95);
            } else if (data.equalsIgnoreCase(TEST5)) {
                mProgressBar.setProgress(96);
            }

            }
        }
    }   
};

public void run() {
    while (true) {
        try {
            Thread.sleep(60);
            myHandler.post(r);
        } catch (InterruptedException e) {
            break;
        }
    }
}

如何让它表现的更好?

编辑 3:

为了更好地解释它必须有多快:

目前我每 80 毫秒收到一条十六进制格式的消息。消息对象有5项:帧格式、数据格式、数据长度、消息ID和数据。在完美的情况下,我每 2-20 毫秒得到一个。

我必须区分 768 条不同的消息。这些消息除以 200(以获得 0.5% 的步长)。

我想要的是一个 ProgressBar,它随着十六进制代码“下雨”和百分比状态的变化而变化和流畅地运行。

一个问题是,我无法影响接收消息的速度。它总是相同的速度。甚至可以如此快速地处理数据吗?

最佳答案

虽然我不确定这是主要问题,但我确实发现您的代码效率低下:

  1. 你正在用这个创建很多 transient 对象

        for (byte i = 0; i < demoRxMsg.dataLength; i++) {
            data = data + Integer.toHexString(demoRxMsg.data[i]) + " ";
        }
    

    对于每个 字节,您至少 创建了两个对象:一个StringBuilder 和一个String 对象(引用here)。如果你想得到一个字符串,至少要像下面这样:

        StringBuilder sb=new StringBuilder();
        for (byte i = 0; i < demoRxMsg.dataLength; i++) {
            sb.append(demoRxMsg.data[i]);
        }
        data=sb.toString();
    
  2. 与比较字符串不同,比较原始字节会更快,这样您就可以完全跳过任何对象创建。

  3. 我假设在第一个和最后几个数据 block 之间,中间有相当多的数据,但在您当前的实现中,那些不影响 UI 的数据仍将在 UI 线程上进行检查,而不是仅在确定需要更新 UI 时运行 mProgressBar.setProgress(progress);。未经测试的代码:

    class RxThread extends Thread {
    private static final String TEST = "0 0 0 0 0 40 0 0 ";
    private static final String TEST2 = "0 1 0 0 0 41 0 0 ";
    private static final String TEST3 = "2 bb 0 0 2 fb 0 0 ";
    private static final String TEST4 = "2 bd 0 0 2 fd 0 0 ";
    private static final String TEST5 = "2 be 0 0 2 fe 0 0 ";
    
    Handler myHandler = new Handler();
    
    public void run() {
    while (true) {
        try {
            Thread.sleep(60);
    
            demoRxMsg = new MessageStructure();
    
            int progress = -1;
            while (rxChannel.receiveMessage(demoRxMsg) == ReturnCode.SUCCESS) {
    
                String data = "";
                String format = "";
    
                rxChannel.receiveMessage(demoRxMsg);
    
                if (demoRxMsg.frameFormat == API_ADK.STANDARD_FRAME) {
                    format = "SFF";
                } else {
                    format = "EFF";
                }
                for (byte i = 0; i < demoRxMsg.dataLength; i++) {
                    data = data + Integer.toHexString(demoRxMsg.data[i])
                            + " ";
                }
    
                if (data.equalsIgnoreCase(TEST)) {
                    progress = 0;
                } else if (data.equalsIgnoreCase(TEST2)) {
                    progress = 1;
                } else if (data.equalsIgnoreCase(TEST3)) {
                    progress = 94;
                } else if (data.equalsIgnoreCase(TEST4)) {
                    progress = 95;
                } else if (data.equalsIgnoreCase(TEST5)) {
                    progress = 96;
                }
            }
            if (progress != -1) {
                final int newProgress = progress;
    
                myHandler.post(new Runnable() {
                    public void run() {
                        mProgressBar.setProgress(newProgress);
                    }
                });
            }
        } catch (InterruptedException e) {
            break;
        }
    }
    

    }

关于java - 快速处理数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21398631/

相关文章:

java - 我可以在运行时更改spring注入(inject)的实现类吗?

java - Joda Time 将包含在 Java 7 中?

ruby - 为什么 Ruby 中没有竞争条件

java - 安卓。如何捕捉键盘隐藏的时刻?

c++ - 使用#include<thread> 创建线程时出现段错误

multithreading - golang除了例程还有处理进程和线程的能力吗

java - 在 war 文件中部署 SQLite 数据库文件并使用正确的 url 访问

java - ANTLR4 如何制作否定连接

android - 保存到没有 SD 卡的设备

android - Xamarin Studio 中禁用了目标平台?