обработчик Android для последовательных задержек

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

Мой подход таков: поместите слова предложения в массив (и, в конечном итоге, длину каждой работы, но на данный момент просто предположим, что 1000 мс каждая); Запишите слово в textViewPartial; задержка длины слова; Добавьте следующее слово в предложение и напишите его в textViewPartial....и т.д.

Но я не могу определить время. Прочитайте все, что я могу найти об обработчике и асинхронности, и лучшее, что я могу придумать, это следующее: я помещаю обработчик с задержкой в ​​​​цикле for. Мой мозг говорит, что он будет задерживать каждый раз, когда цикл зацикливается, но вы можете видеть из логарифмического вывода, что это не так. Существует только одна задержка перед запуском цикла for. Это мой первый пост, и я не понимаю, как вы, ребята, получаете свой цветной код из Eclipse, поэтому я надеюсь, что он выглядит нормально.

   public class LineOutHanler extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_line_out_hanler);
    TextView t = new TextView(this);
    t=(TextView) findViewById (R.id.textView10);
    String textOut = "Oh how my spleen aches to see you again";
    final TextView textViewPartial = (TextView) findViewById(R.id.textView11);
    final String[] wordsOut = textOut.split(" ");
    final int wordsInSentence = wordsOut.length;
    int[] wordLength = new int[wordsInSentence];
            for (int counter=0;counter<=wordsInSentence-1;counter++){
            wordLength[counter]=wordsOut[counter].length();}
    String partialSentence ="";
    for (int counter=0; counter<=wordsInSentence-1; counter++){   
            String  c= addWordsOut(wordsOut[counter], partialSentence);
            textViewPartial.setText(c);
            partialSentence = c;
            Log.d("Word", partialSentence);
    final String partialOut=c;
    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
      @Override
      public void run() {
                        textViewPartial.setText(partialOut);
            Log.d("Handler", partialOut);
        }
    } , 2000);}
    }
public String addWordsOut (String part, String upToHere)  {
upToHere=upToHere+" " + part;
return upToHere;
}
}

и вывод логарифма:

10-19 23:07:32.248: E/cutils-trace(39): Error opening trace file: No such file or directory (2)
10-19 23:07:32.368: D/AudioSink(39): bufferCount (4) is too small and increased to 12
10-19 23:07:32.379: D/Word(821):  Oh
10-19 23:07:32.379: D/Word(821):  Oh how
10-19 23:07:32.388: D/Word(821):  Oh how my
10-19 23:07:32.388: D/Word(821):  Oh how my spleen
10-19 23:07:32.388: D/Word(821):  Oh how my spleen aches
10-19 23:07:32.388: D/Word(821):  Oh how my spleen aches to
10-19 23:07:32.388: D/Word(821):  Oh how my spleen aches to see
10-19 23:07:32.398: D/Word(821):  Oh how my spleen aches to see you
10-19 23:07:32.398: D/Word(821):  Oh how my spleen aches to see you again
10-19 23:07:33.328: I/Choreographer(288): Skipped 30 frames!  The application may be doing too much work on its main thread.
10-19 23:07:33.368: I/ActivityManager(288): Displayed com.example.testtextout/.LineOutHanler: +1s820ms
10-19 23:07:35.320: W/AudioFlinger(39): write blocked for 1091 msecs, 1 delayed writes, thread 0x40e0b008
10-19 23:07:35.320: D/Handler(821):  Oh
10-19 23:07:35.329: D/Handler(821):  Oh how
10-19 23:07:35.329: D/Handler(821):  Oh how my
10-19 23:07:35.329: D/Handler(821):  Oh how my spleen
10-19 23:07:35.329: D/Handler(821):  Oh how my spleen aches
10-19 23:07:35.329: D/Handler(821):  Oh how my spleen aches to
10-19 23:07:35.339: D/Handler(821):  Oh how my spleen aches to see
10-19 23:07:35.339: D/Handler(821):  Oh how my spleen aches to see you
10-19 23:07:35.339: D/Handler(821):  Oh how my spleen aches to see you again
10-19 23:08:30.588: D/dalvikvm(396): GC_FOR_ALLOC freed 452K, 15% free 3047K/3556K, paused 40ms, total 65ms
10-19 23:25:42.149: D/dalvikvm(288): GC_FOR_ALLOC freed 850K, 31% free 5593K/7996K, paused 99ms, total 117ms

Первый вопрос - правильный ли это подход? Второй вопрос - как заставить его работать?

Большое спасибо.


person dulciepercy    schedule 20.10.2013    source источник


Ответы (1)


Проблема в вашем цикле for. Когда вы публикуете runnable, вы всегда публикуете для запуска 2000 мс в будущем от текущего момента времени. Когда ваш код запускается, он публикует эти действия почти одновременно. Таким образом, вы видите, что ваш вывод происходит через 2 секунды, происходит в то же время. Вместо этого вы можете сделать то, что я делаю ниже, где я опубликую его в будущем, кратном 2000 мс, в зависимости от того, над каким словом вы работаете.

for (int counter=0; counter<=wordsInSentence-1; counter++){   
        String  c= addWordsOut(wordsOut[counter], partialSentence);
        textViewPartial.setText(c);
        partialSentence = c;
        Log.d("Word", partialSentence);
        final String partialOut=c;
        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                        textViewPartial.setText(partialOut);
                        Log.d("Handler", partialOut);
               }
        } , 2000*(counter+1));
}

Что касается вашей реализации, я бы рекомендовал публиковать каждый новый исполняемый файл по мере завершения предыдущего. В противном случае вы могли бы создать и опубликовать много исполняемых модулей, излишне потребляя память и усложняя очистку обработчиков. Для первоначального POC это не так уж плохо и может быть легко изменено позже.

person MJD    schedule 20.10.2013
comment
Большое спасибо, что работает. Но вы предлагаете, чтобы я сам очищал runnables? Я вижу, что это будет хорошей практикой. Я должен буду изучить это. - person dulciepercy; 20.10.2013
comment
Я точно не помню, но я не верю, что ваши runnables автоматически очищаются, если, например, ваша активность останавливается. Если бы я использовал ваше приложение, я был бы раздражен, если бы оставил ваше приложение, а ваша книга продолжала читаться в фоновом режиме! Для проверки лучше всего проверить документацию. - person MJD; 20.10.2013