Android: эффективен ли цикл while?

В настоящее время я использую следующую конструкцию:

while(continue)
{
    if(somethingChanged)
    {
        draw();
    }
}

Является ли этот способ ожидания эффективным или есть лучший способ сделать это?

--

По запросу, дополнительная информация:

Я рисую на SurfaceView, при этом Thread блокирует Canvas и вызывает метод onDraw(Canvas). Когда то, что я нарисовал, не изменилось, мне не нужно вызывать метод onDraw(Canvas), поэтому я сохраняю логическое значение somethingChanged.

Кроме того, когда я касаюсь экрана, я рисую, скажем, круг в точке касания, поэтому, когда я касаюсь экрана, что-то изменилось.


person nhaarman    schedule 14.04.2011    source источник
comment
Найдена неверная информация. Не могу ответить.   -  person Mudassir    schedule 14.04.2011
comment
Что вы ждете, чтобы изменить? Во что ты втягиваешься?   -  person Jim Blackler    schedule 14.04.2011


Ответы (5)


Вы также можете использовать wait() и сделать другие потоки notify() этим, когда что-то изменилось (если somethingChanged изменено другими потоками).

person Guillaume Brunerie    schedule 14.04.2011
comment
Но является ли это «лучшим» способом, чем запуск цикла, с точки зрения эффективности? - person nhaarman; 14.04.2011
comment
Да, конечно, во время wait() ваш поток будет приостановлен и будет использовать 0% ЦП вместо 100% (если вы используете бесконечный цикл). И дисплей будет обновляться именно тогда, когда вам нужно. С sleep() вы по-прежнему будете использовать очень мало ЦП, но отрисовка не будет точно в реальном времени. - person Guillaume Brunerie; 14.04.2011

Вы, вероятно, делаете игру, я рекомендую эту статью: http://dewitters.koonsolo.com/gameloop.html Есть очень хорошие возможные решения для вашего запроса.

person WarrenFaith    schedule 14.04.2011
comment
Действительно, это очень хорошее чтение. Но если вашей игре не нужно перерисовываться при бездействии пользователей, то вы скорее всего не найдете ответ на свой вопрос (в статье рассматриваются только игры, где вы хотите иметь самый высокий FPS) - person Guillaume Brunerie; 14.04.2011

Android имеет лучший механизм в отношении циклов простоя, чем подход std java. Он состоит из Looper и Handler, которые делают всю работу за вас:

Handler myHandler;
...
public void run() { 

       Looper.prepare(); //this tells Android that your thread will contain a loop

       myHandler = new Handler() {

              public void handleMessage(Message msg) {
                      draw();  
              }
       };
Looper.loop; //starts the loop
}

Все, что вам нужно сделать, чтобы вызвать метод рисования, — это отправить сообщение этому обработчику вместо установки логической переменной var.

Message mess;
myHandler.sendMessage(mess)

Таким образом, вы также можете отправить любой объект в этом сообщении в цикл, а Android сделает за вас синхронизацию потоков и очередь сообщений. И, что немаловажно, еще и эффективно.

person Rigoroth    schedule 14.04.2011

Если ничего не изменилось, это бесконечный цикл, который, скорее всего, будет использовать 100% процессор, поэтому я бы сказал, что вы должны хотя бы добавить несколько вызовов Thread.sleep(), чтобы дать другим потокам возможность что-то сделать (например, изменить значение somethingChanged)

person Heiko Rupp    schedule 14.04.2011

Обычно в бесконечных циклах у вас должен быть какой-то механизм, чтобы он не занимал все время процессора. Это делается, например, со сном. Даже короткий сон облегчит использование процессора. Предполагая, что этот код находится в потоке:

while(continue)
{
    if(somethingChanged)
    {
        draw();
    }
    Thread.sleep( mySleepTime );
}
person Void    schedule 14.04.2011
comment
Значит, сна всего 30 мс будет достаточно? (Чтобы мой круг двигался гладко) - person nhaarman; 14.04.2011