更改UI的定时事件?

时间:2013-03-03 00:00:59

标签: android multithreading handler ui-thread

我环顾四周,但我不太确定这是如何工作的,并且唯一真正接近我正在寻找的线程就有404信息。

在一项活动中,我有四张图片。我希望他们每15秒换一个不同的图像,然后我会跟踪哪个图像让他们链接到另一个活动。我有线程工作并发布到System.out.println(),但UI没有改变,我不知道如何允许它。这是我到目前为止所拥有的。

public int curImage1 = 1;
public int curImage2 = 2;
public int curImage3 = 3;
public int curImage4 = 4;

onCreate()方法:

// ...
imagesHandler = new Handler();
startImageSwapping();

Runnable swapImages = new Runnable() {

    @Override
    public void run() {
        handleUpdates();
        imagesHandler.postDelayed(swapImages, 3000);
    }
};

public void handleUpdates() {
    if (curImage1 == 1) {
        ((ImageView) findViewById(R.id.main_image_1)).setImageDrawable(
                getResources().getDrawable(R.drawable.logo));
        curImage1 = 5;
    }
    if (curImage1 == 5) {
        ((ImageView) findViewById(R.id.main_image_1)).setImageDrawable(
                getResources().getDrawable(R.drawable.main_image_1));
        curImage1 = 1;
    }
    System.out.println("TEST");
}

public void startImageSwapping() {
    imageThreadIsRunning = true;
    swapImages.run();
}

public void stopImageSwapping() {
    imagesHandler.removeCallbacks(swapImages);
    imageThreadIsRunning = false;
}

应用更改后的当前代码。仍然没有这样做,但希望保持这篇文章更新为其他任何碰到它的人。

Runnable swapImages = new Runnable() {

    @Override
    public void run() {
        runOnUiThread(new Runnable() {

            @Override
            public void run() {
                if (curImage1 == 1) {
                    ((ImageView) findViewById(R.id.main_image_1)).setImageDrawable(
                            getResources().getDrawable(R.drawable.logo));
                    curImage1 = 5;
                }
                if (curImage1 == 5) {
                    ((ImageView) findViewById(R.id.main_image_1)).setImageDrawable(
                            getResources().getDrawable(R.drawable.main_image_1));
                    curImage1 = 1;
                }
                System.out.println("TEST");
            }
        });
        imagesHandler.postDelayed(swapImages, 3000);
    }
};

public void startImageSwapping() {
    imageThreadIsRunning = true;
    swapImages.run();
}

public void stopImageSwapping() {
    imagesHandler.removeCallbacks(swapImages);
    imageThreadIsRunning = false;
}

@Override
protected void onDestroy() {
    stopImageSwapping();
    super.onDestroy();
}

@Override
protected void onPause() {
    stopImageSwapping();
    super.onPause();
}

@Override
protected void onStop() {
    stopImageSwapping();
    super.onStop();
}

@Override
protected void onStart() {
    if (!imageThreadIsRunning)
        startImageSwapping();
    super.onStart();
}

@Override
protected void onResume() {
    if (!imageThreadIsRunning)
        startImageSwapping();
        super.onResume();
}

3 个答案:

答案 0 :(得分:0)

如果您使用runOnUiThread

Runnable swapImages = new Runnable()
{
    @Override
    public void run()
    {
            runOnUiThread(new Runnable()
            {
                @Override
                public void run()
                {
                     handleUpdates();
                 }
            });
            imagesHandler.postDelayed(swapImages, 3000);
    }
};

修改:

很抱歉,但你的代码让我很困惑。如果我从头开始写,我会这样做:

public class Whatever extends Activity implements Runnable {
    ImageView iv;
    Switcher switcher;
    Thread thread;
    Handler handler = new Handler();
    public int curImage ;
    public final int curImage1 = 1;
    public final int curImage2 = 2;
    public final int curImage3 = 3;
    public final int curImage4 = 4;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        iv = (ImageView) findViewById(R.id.imageLogoDown);
        iv.setImageResourse(R.drawable.main_image_1);
            curImage = curImage1;

            switcher = new Switcher(this, handler);
        }



    /**
     * This class will implement the timer, calling run() on the UI thread each
     * time the timer elapses.
     */
    public class Switcher implements Runnable {
        private boolean _running = true;
        private Handler _handler;
        private Runnable _runnable;

        public Switcher(Runnable runnable, Handler handler) {
            _runnable = runnable;
            _handler = handler;
        }

        public void setRunning(boolean running) {
             _running = running;
        }

        @Override
        public void run() {
            while (_running) {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException ex) {
                }
                if (_running)
                    _handler.post(_runnable);
            }
        }
    }

    /**
     * Now on UI thread. Switch views.
     */
    @Override
    public void run() {
        switch (curImage) {
        case curImage1  :
            iv.setImageResourse(R.drawable.main_image_2);
            curImage = curImage2 ;
            break;
        case curImage2 :
            iv.setImageResource(R.drawable.main_image_3);
            curImage = curImage3 ;
            break;
        case curImage3 :
            iv.setImageResource(R.drawable.main_image_4);
            curImage = curImage4 ;
            break;
        case curImage4 :
            iv.setImageResource(R.drawable.main_image_1);
            curImage = curImage1 ;
            break;
        }
    }
  }

}

答案 1 :(得分:0)

线程不会在UI线程上运行,因此UI更新似乎可以正常工作,但不会出现在屏幕上。

this Android Developer blog postAndroid guides,您可以使用runOnUiThread方法或使用方便的类CountDownTimer,而不必进行任何线程处理:

CountDownTimer timer = new CountDownTimer(15000, // 15 second countdown
    99999) // onTick time, not used here
{

     public void onTick(long millisUntilFinished) {
         // Not used in this example
     }

     public void onFinish() {
         handleUpdates();
         timer.start(); // restarts the timer
     }
};
timer.start();

答案 2 :(得分:0)

好吧,我实际上在我的一本书中找到了答案--Android Recipes。这是为了以后可能会发现这个问题的人:

private Runnable timerTask = new Runnable()
{
    @Override
    public void run()
    {
        if(curImage1 == 1)
        {
            mainImage1.setImageDrawable(getResources().getDrawable(R.drawable.logo));
            curImage1 = 5;
        }
        else if(curImage1 == 5)
        {
            mainImage1.setImageDrawable(getResources().getDrawable(R.drawable.main_image_1));
            curImage1 = 1;
        }
        mHandler.postDelayed(timerTask, 3000);
    }
};

@Override
public void onResume()
{
    super.onResume();
    mHandler.post(timerTask);
}

@Override
public void onPause()
{
    super.onPause();
    mHandler.removeCallbacks(timerTask);
}