Как периодически отображать прямоугольник в активности Android

Я хотел бы периодически отображать белый прямоугольник на экране Android; или изменить цвет фона. Например, каждые 500 мс я хочу, чтобы цвет экрана менялся с черного на белый примерно на 200 мс, а затем обратно на черный.

Как лучше всего это сделать? Я попытался с асинхронной задачей, но получил ошибку, что только исходный поток может касаться представления. У меня есть похожая асинтаск, которая звучит периодическим тоном и работает нормально.

РЕШЕНИЕ:

С помощью респондентов я решил свою проблему, создав два таймера: один для черного и один для белого. Черный запускается с задержкой на время, которое я хочу отобразить на белом экране. Оба имеют одинаковую скорость выполнения, поэтому отображается белый экран, а затем, через duration мс, отображается черный экран. Например, экран черный, но мигает белым каждую секунду в течение 200 мс.

    @Override
protected void onResume() {
    super.onResume();

    mBlackTimer = new Timer();
    mBlackTimer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    view.setBackgroundColor(Color.parseColor("#000000"));

                }
            });
        }
    }, duration, (long) (1000 / visionPeriod));

    mWhiteTimer = new Timer();
    mWhiteTimer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    view.setBackgroundColor(Color.parseColor("#ffffff"));
                }
            });

        }
    }, 0, (long) (1000 / visionPeriod));
}

person PerceptualRobotics    schedule 06.01.2014    source источник
comment
вы можете получить доступ к свойствам пользовательского интерфейса из фона, но сначала вы должны получить доступ к потоку пользовательского интерфейса, вызовите getActivity().runOnUiThread(); если вы хотите что-то изменить и поместить логику ожидания вне этого потока   -  person Daniel Bo    schedule 06.01.2014


Ответы (3)


Вы можете использовать класс таймера для выполнения некоторой задачи с повторяющимся интервалом:

//Declare the timer
Timer t = new Timer();

//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        //Called each time when 1000 milliseconds (1 second) (the period parameter)
    }    
},
//Set how long before to start calling the TimerTask (in milliseconds)
0,
//Set the amount of time between each execution (in milliseconds)
1000);
person Meenal    schedule 06.01.2014
comment
Я попробовал ваше предложение с view.setBackgroundColor(Color.parseColor(#FFFFFF)) в методе запуска, но получил ту же ошибку, что только исходный поток может касаться представления. - person PerceptualRobotics; 06.01.2014

AsyncTask в основном используется для выполнения фоновых действий, таких как загрузка данных с удаленного сервера. Он работает в своем собственном потоке, поэтому, когда из AsyncTask вы пытаетесь получить доступ к любому представлению своей деятельности, он выдает эту ошибку that only the original thread can touch the View.

Вы можете использовать класс Timer или класс AlarmManager для повторяющихся задач. Посетите мой предыдущий ответ.

person Vigbyor    schedule 06.01.2014

Создайте метод задачи Timer и внутри timertask и задайте ему периодическую продолжительность 700 мс, покажите черный фон, а затем создайте обработчик для отображения белого фона и задержите его на 500 мс.

попробуйте все это только в uthread

не используйте новый поток или асинхронную задачу следующим образом:

mTimer = new Timer();
    mTtask = new TimerTask() {
        public void run() {
            //set your black background here
            new Handler().postDelayed(new Runnable() {

                @Override
                public void run() {
                    // set your white background here
                }
            }, 500);
        }
    };
    mTimer.schedule(mTtask, 1, 700);
person Ari    schedule 06.01.2014
comment
Я поместил этот код в onResume, но получил эту ошибку. Невозможно создать обработчик внутри потока, который не вызвал Looper.prepare(). Что это значит? - person PerceptualRobotics; 06.01.2014