如何将变量传递给postDelayed的可运行对象?

3

我创建了两个从runnable()实现的类。然后我多次调用它们,延迟时间不同。问题是,当我后来运行runnable()时,它需要知道postdelay被调用时变量的值,而不是实际运行时的值。

我认为我现在需要做的是在调用post delay时将变量传递到runnable()实例中。但是,我无论如何都无法弄清楚如何做到这一点。以下是参考源代码:

public void PlaySequence() throws InterruptedException{

for(int i = 0;i<level;i++){
    mHandler.postDelayed(mToggleButtonOn, (i+1)*playbackOffTime);
    mHandler.postDelayed(mToggleButtonOff, (i+1)*playbackOnTime);           
    currentProgIteration++;
}        
currentProgIteration=0;     
}

private Runnable mToggleButtonOn = new Runnable() {

public void run() {
    try {
            if(Sequence[currentProgIteration]==0){
                ImageCard[0].setImageDrawable(getResources().getDrawable(R.drawable.yellow));
            }
            else if(Sequence[currentProgIteration]==1){
                ImageCard[1].setImageDrawable(getResources().getDrawable(R.drawable.blue));
            }
            else if(Sequence[currentProgIteration]==2){
                ImageCard[2].setImageDrawable(getResources().getDrawable(R.drawable.red));
            }
            else if(Sequence[currentProgIteration]==3){
                ImageCard[3].setImageDrawable(getResources().getDrawable(R.drawable.green));
            }                   
        }
     catch (IllegalStateException e) {
        e.printStackTrace();
    }

}
};

private Runnable mToggleButtonOff = new Runnable() {

public void run() {
    Log.d("Info", "running Off currentProgIteration: "+currentProgIteration);

    try {
            if(Sequence[currentProgIteration]==0){
                ImageCard[0].setImageDrawable(getResources().getDrawable(R.drawable.darkyellow));
            }
            else if(Sequence[currentProgIteration]==1){
                ImageCard[1].setImageDrawable(getResources().getDrawable(R.drawable.darkblue));
            }
            else if(Sequence[currentProgIteration]==2){
                ImageCard[2].setImageDrawable(getResources().getDrawable(R.drawable.darkred));
            }
            else if(Sequence[currentProgIteration]==3){
                ImageCard[3].setImageDrawable(getResources().getDrawable(R.drawable.darkgreen));
            }                   
        }
    catch (IllegalStateException e) {
        e.printStackTrace();
    }

}
};

这些可运行程序正在使用全局变量currentProgIteration,但是当它们在延迟后运行时,该变量已经被重置为0。

感谢任何建议。

2个回答

3
最简单的方法可能是使用匿名的Runnable。
final int delay = (i+1)*playbackOffTime;
mHandler.postDelayed(new Runnable() {
   final Color[] colours = { R.drawable.yellow, R.drawable.blue, R.drawable.red, R.drawable.green } ;
   public void run() {
        try {
           // can use "delay" here
           int seq = Sequence[currentProgIteration];
           ImageCard[seq].setImageDrawable(getResources().getDrawable(colours[seq]));
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
    }
});

有没有办法在使用它的同时仍然可以调用“removeCallbacks(...)”来取消匿名的Runnable?我想不出来。 - Cory Trese
@CoryTrese 如果 mHandler 支持的话,那当然可以。如果您使用 ExecutorService,则会返回一个可取消的 Future。 - Peter Lawrey

0

就像 Peter 所说的,您可以使用匿名的 Runnable

要实现 removeCallbacks(...),您可以使用标记来删除可运行项:

创建顶级标记来区分发布到 MessageQueue 上的可运行项,例如

val animToken = Any()

为了跟踪您的可运行项,请使用以下扩展:

fun Handler.postDelayedWithToken(token: Any, delayInMillis: Long, runnable: Runnable) {
    postAtTime(runnable, token, SystemClock.uptimeMillis() + delayInMillis)
}

示例用法: handler.postDelayedWithToken(animToken, 3000L, { hideSomething() })

为了处理(例如:在onPause / onStop / onDestroyView之前):

handler.removeCallbacksAndMessages(animToken)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接