Java 安卓:Can';t在for/while循环中执行Handler.postDelayed,但不包含IndexOutOfBoundsException

Java 安卓:Can';t在for/while循环中执行Handler.postDelayed,但不包含IndexOutOfBoundsException,java,android,Java,Android,我想以编程方式更改ImageView的背景,但是在单独线程上的for/while循环中。在我的示例中,在名为“lights”的ArrayList中有3560个ImageView。我想在一段短暂的延迟后改变循环中每个人的背景,即每秒改变一次 ArrayList<ImageView> lights = new ArrayList<>(); int numberOfLights = 3560; ArrayList lights=new ArrayList(); int num

我想以编程方式更改ImageView的背景,但是在单独线程上的for/while循环中。在我的示例中,在名为“lights”的ArrayList中有3560个ImageView。我想在一段短暂的延迟后改变循环中每个人的背景,即每秒改变一次

ArrayList<ImageView> lights = new ArrayList<>();
int numberOfLights = 3560;
ArrayList lights=new ArrayList();
int numberOfLights=3560;
我最初使用了这段代码,但有一个问题,“I”必须声明为final,因为它是从内部类调用的,如果for循环需要它,这是不可能的

Handler h = new Handler();

for( int i = 0; i < numberOfLights; i++) {

    h.postDelayed(new Runnable() {
        @Override
        public void run() {
            lights.get(i).setBackgroundResource(R.drawable.light_white);
        }

    }, 1000);
}
Handler h=new Handler();
对于(int i=0;i
因此,我尝试使用全局变量:

Handler h = new Handler();
counter = 0;

for( ; counter < numberOfLights; counter++) {

    h.postDelayed(new Runnable() {
        @Override
        public void run() {
            lights.get(counter).setBackgroundResource(R.drawable.light_white);
         }

    }, 1000);
}
final int iCopy = i;
Handler h=new Handler();
计数器=0;
用于(;计数器
这就好像完全忽略了此计数器,h.postDelayed即使在计数器大于numberOfLights时也会运行,我尝试了使用Thread.sleep调用的普通线程,结果是“只有创建视图层次结构的原始线程才能接触其视图”,并且还使用了runOnUiThread方法,但运气不佳


非常感谢您的帮助。

只需创建一个新变量:

Handler h = new Handler();
counter = 0;

for( ; counter < numberOfLights; counter++) {

    h.postDelayed(new Runnable() {
        @Override
        public void run() {
            lights.get(counter).setBackgroundResource(R.drawable.light_white);
         }

    }, 1000);
}
final int iCopy = i;
然后在你的Runnable中使用它

Handler h = new Handler();

for( int i = 0; i < numberOfLights; i++) {
    final int iCopy = i;

    h.postDelayed(new Runnable() {
        @Override
        public void run() {
            lights.get(iCopy).setBackgroundResource(R.drawable.light_white);
        }

    }, 1000);
}
Handler h=new Handler();
对于(int i=0;i
但是,如果同时修改
灯光
,这可能无法避免IndexOutOfBoundsException。在这种情况下,范围检查或复制阵列或灯光将解决您的问题。

使用for each循环。它比传统的循环更优雅,在这种情况下,您可以将局部变量设置为final

for(final ImageView light: lights) {

    h.postDelayed(new Runnable() {
        @Override
        public void run() {
            light.setBackgroundResource(R.drawable.light_white);
        }

    }, 1000);
}
另外,将处理程序定义为

Handler h = new Handler(Looper.getMainLooper());

为了在UI线程上运行代码

这是异常所说的,您不能从其他线程接触UI。您应该考虑查看AynCtEngor或使用RunOnthRead())3560 IVIEVIEWS…糟糕的主意