Загрузка Android и отображение большого количества изображений в ImageView (покадровая анимация) зависает в определенные моменты - PullRequest
1 голос
/ 19 февраля 2010

Я создал приложение, которое показывает около 250 изображений в ImageView. Изображения загружаются одно за другим, 15-30 изображений в секунду. По сути, все это создает иллюзию вращающегося трехмерного объекта, по крайней мере, так и должно быть. Проблема в следующем, приложение зависает при загрузке определенных изображений (т.е. я вижу несколько секунд плавной анимации, а затем анимация зависает, прыгает на 10-15 кадров (изображений) вперед и продолжается. Это всегда происходит в одних и тех же местах цикла анимации. Я думал, что у Android может не хватить ресурсов для обработки чего-то подобного, поэтому я изменил размер изображения до половины их размера, но это не помогло. Я пробовал буферизовать изображения, но это тоже не помогло (на самом деле, возможно, немного, я думаю, что анимация выглядит немного более плавной). А теперь самая странная вещь. Я использую сенсорный экран, чтобы позволить пользователям «вращать» трехмерный объект на этих изображениях, и во время вращения я снова испытываю эти зависания точно в тех же местах, что и при анимации.

Все изображения в формате .png, их размер варьируется от 15 кБ до 40 КБ.

Я использую следующий код для анимации:

new Thread(new Runnable() {

   @Override
   public void run() {
    while (!stopStartupAnimation && li < images_360.length) {
     final int fli = li;
     handler.post(new Runnable() {

      @Override
      public void run() {
       //Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
       //imageCanvas.setImageResource(images_360[fli]);
       imageCanvas.setImageBitmap(imageStackNext.pop());
       System.out.println("rawX = " + fli);
      }
     });
     int ti = fli +25;
     if(ti > images_360.length-1){
      ti = ti - images_360.length;
     }
     imageStackNext.push(BitmapFactory.decodeResource(getResources(), images_360[ti]));
     synchronized (this) {
      try {
       wait(1000 / 25);
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
     }
     li++;
     li++;
     if (li >= images_360.length) {
      li = 0;
     }
    }
   }
  }).start();

Ответы [ 2 ]

1 голос
/ 19 февраля 2010

Во-первых, 15-40 КБ - это их сжатая форма. Несжатые, как Bitmaps, они, вероятно, значительно больше. 250 из них могут использовать много МБ ОЗУ, что не очень хорошая идея.

Во-вторых, учитывая выбор между использованием OpenGL для 3D (что является его целью), или примитивами 2D-рисования на Canvas, или с помощью ImageView, вы выбрали худший вариант.

В-третьих, postRunnable() не вступает в силу немедленно, а скорее помещает вещи в очередь сообщений для обработки основным потоком приложения, когда у него появляется такая возможность. Если он связан - скажем, обрабатывает сенсорные события - он может пропустить некоторые, казалось бы, избыточные ImageView перерисовки, или заставить их пройти так быстро, что, кажется, не произойдет. Все ваши 40 мс wait() гарантируют, что вы поднимаете события только каждые 40 мс, а не то, что они будут рисовать каждые 40 мс. Кроме того, вы могли бы проще использовать postDelayed() для 40 мс времени.

0 голосов
/ 26 мая 2016

Растровые изображения должны быть загружены эффективно.Смотрите пример на официальной странице: https://developer.android.com/training/displaying-bitmaps/index.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...