【问题标题】:How can I pass a variable into a postdelayed runnable?如何将变量传递给延迟后的可运行对象?
【发布时间】:2011-10-23 16:42:37
【问题描述】:

我创建了两个从 runnable() 实现的类。然后我给他们打了几次电话,但延迟不同。问题是,当我稍后运行 runnable 时,它​​需要在调用 postdelay 时知道变量的值,而不是在实际运行时。

我认为我现在需要做的是在调用 post delay 时将变量传递给可运行实例。但是对于我的生活,我不知道该怎么做。以下是源代码供参考:

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();
    }

}
};

runnables 正在使用全局变量 currentProgIteration,但在延迟后运行时,该变量已被设置回 0。

感谢您的任何建议。

【问题讨论】:

    标签: java runnable postdelayed


    【解决方案1】:

    最简单的方法可能是使用匿名 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?我想不通。
    • @CoryTrese 当然如果 mHandler 支持。如果你使用 ExecutorService,它会返回一个 Future,它可以被 cancel()led。
    【解决方案2】:

    正如彼得所说,您可以使用匿名Runnable

    要使 removeCallbacks(...) 成为可能,您可以使用令牌删除可运行对象:

    为发布到 MessageQueue 上的不同 Runnable 创建顶级令牌,例如

    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)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-19
      • 2016-12-02
      • 1970-01-01
      • 2020-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多