java - 线程问题,字段不更新

标签 java android multithreading

Asycntask的onprogressupdate总是被调用,:

    @Override
    protected void onProgressUpdate(Integer... values) {
        pbSubStatus.incrementProgressBy(values[1]);
        rawNum = values[0];
                     ...
    }

在外部类上:

    private double getCurrentTime() {
    return currentTime;
}
private void doSomethingOnThread() {
    LinearLayout layout = (LinearLayout) findViewById(R.id.main);
    sMeter = new Meter(context);
    layout.addView(sMeter);
    final Handler mHandler = new Handler();
    new Thread() {
        @Override
        public void run() {

            while (running) {
                previousTime = getCurrentTime();
                previousNum = getRawNum();
                try {
                    Thread.sleep(1500);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                currentTime=getCurrentTime();
                currentNum = getRawNum();
                mHandler.post(mUpdateResults);
            }
        }
    }.start();
}
final Runnable mUpdateResults = new Runnable() {
    public void run() {
        updateResultsInUi();
    }
};
private void updateResultsInUi() {
    if(previousNum>currentNum){
        return;//TODO
    }else{
        int temp=currentNum-previousNum;//Problem here, both num are same.
        double timeTemp=currentTime-previousTime; 
        someField=  (float)( temp/timeTemp);
    }
    sMeter.setTarget(someField);//this should be last line to be executed in this snippt
}

所以问题是 previousNum 和 currentNum 总是返回相同的数字。我希望线程等待 1.5 秒以从 onProgressupdate 获取新的 (getRawNum())。但我不明白他们返回的是相同的号码。感谢您的任何建议。

最佳答案

我认为这部分没有达到您想要的效果:

while (running) {
    previousTime = getCurrentTime();
    previousNum = getRawNum();
    try {
        Thread.sleep(1500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    currentTime=getCurrentTime();
    currentNum = getRawNum();
    mHandler.post(mUpdateResults);
}

例如,假设它在 time=0 时开始执行。在第一次迭代结束时,您将得到:

previousTime = 0
currentTime  = 1500

...但是,循环将立即开始第二次迭代,然后您将得到:

previousTime = 1500
currentTime  = 1500

...然后它将再 hibernate 1500 毫秒,并将 currentTime 设置为 3000,然后立即开始下一次迭代,并将 previousTime 设置为 3000。

所以问题是,在绝大多数情况下,您的代码会将 currentTimepreviousTime 设置为相同的值。它们具有不同值的唯一时间是一次迭代结束和下一次迭代开始之间的极短时间跨度。

解决此问题的快速方法如下:

currentTime = getCurrentTime();
currentNum = getRawNum();
while (running) {
    try {
        Thread.sleep(1500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    previousTime = curentTime;
    previousNum = currentNum;
    currentTime=getCurrentTime();
    currentNum = getRawNum();
    mHandler.post(mUpdateResults);
}

更好的方法可能是重构代码,使用循环缓冲区之类的东西来跟踪最后的n个样本和样本时间戳。然后,您可以简单地定期查询新样本,并且在更新 UI 时,您只需将缓冲区中最新的内容与紧邻其之前的内容进行比较。

对于 UI 中未更新的字段,请确保尝试更新它们的代码正在主线程上运行。

关于java - 线程问题,字段不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12344575/

相关文章:

java - 如何在TimePicker中设置自定义时间

Java、Swing - JPanel 没有按预期出现在 JFrame 中

java - 推荐的 Maven 存储库搜索引擎?

java - 检查Jlabel是否有Icon

android - 使用 Samsung Vibrant 运行 adb 时遇到问题

android - 在 Maven android 项目中通过命令行运行 Debug模式

java - 为什么 notifyAll() 没有唤醒这个例子中的所有线程?

ios - 什么是iOS sleep 功能

c++ - 使用 QT5_ADD_RESOURCES 和使用 CMake 进行多线程编译时损坏的资源 .cpp 文件

Android:有没有办法禁用通知 bundle ?