一个处理程序上的多个Runnables,错误的重复行为

时间:2017-06-27 20:21:02

标签: android multithreading runnable android-handler

在我的Android应用程序中,我需要在不同的时间间隔内更新UI的不同部分(实际上是Fragment内的ViewPager。为此,我创建了{{1使用Handler方法,Runnables应该按照预定的时间间隔重复。{}和Runnables。 目前我有1个runnable必须每100毫秒更新一个postDelayed(Runnable, delay),另一个每1000毫秒更新一个TextView,另一个每2000毫秒检查一些东西。

我看到计数器和进度条增加得太快,所以我已经设置了一些代码来检查每次调用ProgressBar方法之间的延迟,并且我发现第一个可运行的是每58毫秒执行一次,进度条每隔508毫秒运行一次。

然后我试图只在Handler(计数器1)上留下第一个Runnable,并且每隔~101 ms调用Run()方法。因此,我认为其他Runnables可能会干扰Message Queue计划。然后,我为每个Runnable创建了一个Handler,但是这样问题在第一个Runnable中持续56~58 ms,在第二个Runnable上持续508~510 ms。

有关此行为发生原因的任何建议?

这是我的代码的一部分:

Run()

StartCounting()方法

private static final int TIME_STEP_COUNTER = 100;
private static final int TIME_STEP_PROGRESS = 1000;
private static final int TIME_STEP_DIRECTOR = 2000;

private Handler counterHandler, progressHandler, directorHandler;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
    // some code here
    directorThread = new DirectorThread(wwp,TIME_STEP_DIRECTOR);

    if(directorHandler == null){
        directorHandler = new Handler();
        directorHandler.post(directorThread);
    }
    startCounting();
}

线程

CounterUpdater

public void startCounting(){

    stdCounterUpdater = new CounterUpdaterThread(textViewCounter,TIME_STEP_COUNTER, increment100ms);
    progressUpdaterThread = new ProgressUpdaterThread(progressBar,TIME_STEP_PROGRESS,textViewPercentage);
    fixerThread = new FixerThread(wwp,TIME_STEP_FIXER);
    if(counterHandler == null){
        counterHandler = new Handler();
    }
    counterHandler.post(stdCounterUpdater);
    if(progressHandler == null){
        progressHandler = new Handler();
    }
    progressHandler.postDelayed(progressBarInitThread, DELAY_INIT_PROGRESS);
    progressHandler.postDelayed(progressUpdaterThread, DELAY_INIT_PROGRESS + INIT_PROGRESS_DURATION);
    counterLayout.setVisibility(View.VISIBLE);
}

ProgressUpdater

class CounterUpdaterThread implements Runnable{

    public CounterUpdaterThread(TextView counterView, long deltaTime, float increment){
     //Constructor with fields initialization
    }
    @Override
    public void run(){
        counter  += increment;
        changeCounterText();
        if(counterHandler != null){
            counterHandler.postDelayed(stdCounterUpdater,deltaTime);
        }
    }
}

DirectorThread

class ProgressUpdaterThread implements Runnable{

    public ProgressUpdaterThread(ProgressBar pBar, long deltaTime, TextView percTW){
        //Fields init
    }

    @Override
    public void run(){
        anim = new ProgressBarAnimation(progressBar, progress, progress + smoothScale);
        progress += smoothScale;
        anim.setDuration(PROGRESS_UPDATE_DURATION);
        progressBar.startAnimation(anim);
        percTW.setText(String.format(Locale.US,"%.1f", progressBar.getProgress()*100f/progressBar.getMax()) + "%");
        if(progressHandler != null){
            progressHandler.postDelayed(progressUpdaterThread,deltaTime);
        }
    }
}

我还检查了这些文章和其他一些问题,但没有结果

Repeating Tasks

Handler Vs Timer

Handlers and Loopers

1 个答案:

答案 0 :(得分:0)

我刚发现问题:关于单个处理程序,但关于在DirectorThread中启动新的回调。只需将onCreateView()方法isStarted设置为true即可解决问题。

根据 pskink 的建议,我已将postDelayed()替换为postAtTime(),因为它恰好更准确。