2013-08-15 2 views
10

Я очень новичок в программировании на Android, поэтому, пожалуйста, простите мою noobie-ness. Я пытаюсь создать очень простое действие, которое будет иметь один TextView в середине макета и просто переключится на другой текст каждые пару секунд. Например, TextView скажет «text1», приостановит на пару секунд, затем скажет «text2 и снова приостановит». В конце концов, я хочу добавить больше текстов и заставить их все цикл один за другим. Я знаю, что это похоже на супер простая вещь, но в настоящее время я в основном пытаюсь узнать о потоках и обработчиках. В любом случае, я прочитал, как мы должны хранить длинные вещи из потока пользовательского интерфейса, чтобы предотвратить ошибку, поэтому я решил использовать обработчик . просто переключаться между 2 текстами на экране, к сожалению, я не могу получить эту работу Вот код:.Приостановка с обработчиком и postDelayed в android

public class MainActivity extends Activity { 

String[] myarray = {"text1" , "text2"}; 
int arraylength = myarray.length; 
int count; 
Handler handler = new Handler(); 

TextView mytexts; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    mytexts = (TextView)findViewById(R.id.my_texts); 
    mytexts.setText(myarray[0]); 

    Thread t = new Thread(new Runnable(){ 
     public void run() { 
      for (int count = 0; count < arraylength; count++){ 
       handler.postDelayed(new Runnable(){ 
        public void run() { 
         mytexts.setText(myarray[1]); 
        }     
       }, 7000); 
      } 
     } 
    }); 
    t.start(); 
    } 
} 

Из того, что я могу видеть в LogCat, обработчик, кажется, бежит postDelayed один за другим (в случае с моим кодом он не ждет 7 секунд, когда postDelay делает еще один postDelayed). Кроме того, я хотел бы сделать 1 в «mytexts.setText (myar ray [1]); «быть таким же, как« count »в цикле for, чтобы он мог быть таким же, как одна из строк в массиве, но это дает мне ошибку. Я застрял в этом часами, и другие примеры, которые я нашел в Интернете, кажутся слишком сложными для кого-то вроде меня, который в основном хочет убрать основы, прежде чем я смогу заняться другими делами. Любая помощь вообще с любым из этого была бы высоко оценена. Спасибо.

+0

Почему вы не удалите 'postDelayed' и использовать' Post' с 'while', а затем сделать некоторые' тему .sleep (время) '? –

+0

@RotaryHeart метод postDelay отправит код, который будет выполнен в основном потоке после задержки. Вам не нужно спать нить. В этом конкретном случае ему вообще не нужна нить! – Ali

+0

@Ali Да, вы правы, я не хотел менять свой код, но чтобы рассказать ему, как это сделать с этим кодом. –

ответ

19

postDelayed не блокирует, что означает, что он добавит его в очередь. Я сделаю это позже. Так что вы, вероятно, видите, все обновления текста происходят вместе на 7-й секунде. Я говорю это, потому что вы - postDelay ing из метода onCreate, когда на самом деле вы, вероятно, захотите сделать это с onResume или даже onPostResume.

Также нет причин создавать поток для добавления runnables в очередь сообщений. Ваш код должен выглядеть следующим образом: (Обратите внимание на время задержки множителя)

@Override 
protected void onResume() { 
    super.onResume(); 
    for (int count = 0; count < arraylength; count++){ 
     handler.postDelayed(new Runnable(){ 
      @Override 
      public void run() { 
       mytexts.setText(myarray[count]); 
      } 
     }, 7000 * (count + 1)); 
    } 
} 
+0

Да, все обновления текста происходят на 7-й секунде. Я немного не понимаю, почему мне не нужно создавать новый поток. Выполняет ли postDelayed 7-секундное ожидание в фоновом потоке автоматически? Я знаю, что это ожидание вызовет ошибку в пользовательском интерфейсе, поэтому я и думал, что мне нужен новый поток. –

+0

У вас есть это, он будет «ждать» за пределами текущего (UI) потока. – JRomero

+0

Awesome. Это очищает вещи. Большое спасибо. –

2

Это потому, что ваша петля устанавливает все ваши обработчики для запуска через 7 секунд не через 7 секунд после друг друга, а через 7 секунд. Вы можете либо добавить метод postDelayed, либо использовать метод postAtTime в обработчике.

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