Java 在特定时间间隔更改背景图像

Java 在特定时间间隔更改背景图像,java,android,Java,Android,我试图开发一个android应用程序,在这个应用程序中,背景每5秒就会改变一次。我编写了如下代码: public class BgView extends Activity implements Runnable { ImageView img; int [] setImg = {R.drawable.one,R.drawable.two}; RelativeLayout layout; @Override protected void onCreate(

我试图开发一个android应用程序,在这个应用程序中,背景每5秒就会改变一次。我编写了如下代码:

public class BgView extends Activity implements Runnable {
    ImageView img;
    int [] setImg = {R.drawable.one,R.drawable.two};
    RelativeLayout layout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bg_view);
        layout = (RelativeLayout) findViewById(R.id.first);
        Thread t = new Thread(new BigView);
            t.start();

    }

    @Override
    public void run() {
        for (int i = 0; i < 2; ++i) {
            layout.setBackgroundResource(setImg[i]);
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

} 
公共类BgView扩展活动实现可运行{
图像视图img;
int[]setImg={R.drawable.one,R.drawable.two};
相对布局;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u bg\u视图);
布局=(RelativeLayout)findViewById(R.id.first);
线程t=新线程(新大视图);
t、 start();
}
@凌驾
公开募捐{
对于(int i=0;i<2;++i){
setBackgroundResource布局图(setImg[i]);
试一试{
睡眠(5000);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
} 
它编译得很好,但当我试图在emulator中运行它时,它在5秒钟后停止了,在
logcat
中,我看到一个异常,它说我不能从其他函数或类似的东西中触摸Activity类视图

因此,我将整个for循环放在onCreate()方法中,现在我没有得到任何异常,但在得到最后一张图像后,我看到的只是一个空白屏幕,持续5秒钟

我知道这个问题已经被重复了,但我只是不想复制粘贴代码……我想知道为什么会发生这种情况,以及如何在最少更改的情况下使其工作

编辑: 我得到以下例外: E/AndroidRuntime(904):android.view.ViewRootImpl$CalledFromErrorThreadException:只有创建视图层次结构的原始线程才能接触其视图。

我想知道为什么将整个for循环放在onCreate()方法中不起作用

将这一行放在ui线程中,就像这样,因为您不能从另一个线程在ui线程中修改

runOnUiThread(new Runnable() {
    @Override
    public void run() 
    {
    layout.setBackgroundResource(setImg[i]);
    }
});
我认为正确的方法是使用闹钟。请参阅此链接


希望这能有所帮助。

您的
运行方法应该重新编写,如下所示:

public void run() {
    for (int i = 0; i < 2; ++i) {
        runOnUiThread(new Runnable() {

            public void run() 
            {
                layout.setBackgroundResource(setImg[i]);
            }
        });

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public void run(){
对于(int i=0;i<2;++i){
runOnUiThread(新的Runnable(){
公开募捐
{
setBackgroundResource布局图(setImg[i]);
}
});
试一试{
睡眠(5000);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}

只有UI线程可以/应该更新UI视图,在您的代码中,您试图直接从新线程更新视图

您应该在活动中创建一个处理程序,然后在所需的时间间隔内从线程调用该处理程序。然后处理程序应该更新UI。尝试代码(我没有编译代码,只是键入了代码,这样可能会有输入错误)

公共类BgView扩展活动实现可运行{
图像视图img;
final int[]setImg={R.drawable.one,R.drawable.two};
相对布局;
接口MyHandler{
void letMeKnow(inti);
}
私有MyHandler=newmyhandler(){
@凌驾
void letMeKnow(int i){
setBackgroundResource布局图(setImg[i]);
}
}
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u bg\u视图);
布局=(RelativeLayout)findViewById(R.id.first);
线程t=新线程(新大视图);
t、 start();
}
@凌驾
公开募捐{
对于(int i=0;i<2;++i){
handler.letMeKnow(i);
试一试{
睡眠(5000);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}

}`

谢谢你的时间(+1)…我明白你的意思,但为什么在主线程中放入for循环没有起作用..我的意思是我没有得到任何异常,但我得到的只是5秒钟的空白屏幕,然后我只看到了最后的背景?谢谢你的时间(+1)…好吧,但是为什么第二种方法不起作用…我的意思是当我把整个for循环放在主方法中时(它没有给出任何例外)我被黑屏显示了5秒钟,然后最后一张图像被显示出来……你能解释一下吗?@NawedShaikh当你调用线程时。从onCreate方法睡眠实际上是让UI线程睡眠,因此UI不会被更新。
public class BgView extends Activity implements Runnable {
    ImageView img;
    final int [] setImg = {R.drawable.one,R.drawable.two};
    RelativeLayout layout;

    interface MyHandler {
     void letMeKnow(int i);
    }
    private MyHandler handler = new MyHandler(){

       @Override
       void letMeKnow(int i){
         layout.setBackgroundResource(setImg[i]);
       }
    }
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_bg_view);
    layout = (RelativeLayout) findViewById(R.id.first);
    Thread t = new Thread(new BigView);
        t.start();

}

@Override
public void run() {
    for (int i = 0; i < 2; ++i) {
        handler.letMeKnow(i);
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}