Подтвердить что ты не робот

Странная проблема с производительностью Galaxy Tab

Я работаю над учебником 2d и смог проверить текущую часть учебника на вкладке Samsung Galaxy Tab.

Учебник просто перемещает значок по умолчанию случайно по экрану. При нажатии я создаю новую движущуюся иконку. Все работает отлично (постоянно 60 кадров в секунду) на Галактике, пока у меня есть 25 элементов или меньше на экране.

С 26-м элементом частота кадров снижается до 25 кадров в секунду.

Когда я изменяю размер/размер изображения на гораздо больший, я достигаю менее 25 кадров в секунду до 26-го элемента. Ничего страшного. Но при некотором невоспроизводимом количестве элементов кадр падает (в основном больше) на 10 кадров в секунду до 1 кадра в секунду.

В моем Nexus One я могу добавить 150 элементов и по-прежнему иметь 50 кадров в секунду.

Что я сделал: я изменил переменную bitmap на статическую, поэтому не каждый элемент имеет свой собственный образ, но все используют то же самое. Это устранило поведение, но я сомневаюсь, что это решение является хорошим. Магическое число 25 предполагает, что я могу использовать только 25 различных изображений таким образом.

Есть ли у кого-нибудь идеи, что может вызвать такое поведение? Это ошибка в модифицированной версии Android от Samsung?

Мой образец проекта eclipse доступен. Я был бы признателен, если бы какой-либо владелец Samsung проверил их производительность с образцом.

изменить

Сотрудник нашел решение. Он изменил способ загрузки растрового изображения из

mBitmap = BitmapFactory.decodeResource(res, R.drawable.icon);

к

mBitmap = BitmapFactory.decodeStream(new BufferedInputStream(res.openRawResource(R.drawable.icon)));

Но мы по-прежнему не понимаем, почему он работает таким образом...

4b9b3361

Ответ 1

Ну, я смотрю на ваш проект, и все кажется прекрасным, но у меня есть одна идея о том, что приводит к снижению частоты кадров.

Вы выделяете объекты во время выполнения. Если вы этого не сделаете, это заставит вас создавать все объекты при запуске, и поэтому вы должны заметить значительное падение напрямую (если мое решение не решит вашу проблему).

Это сказало; Я не уверен, будет ли пул объектов решить вашу проблему, но вы можете попробовать. Инициализируйте свои объекты в конструкторе и вместо этого вызова в onTouchEvent():

new Element(getResources(), (int) event.getX(), (int) event.getY())

У вас должно быть что-то вроде mElement.add(objectPool.allocate()), где пул объектов находит неиспользуемый объект в пуле. Кроме того, мы должны иметь определенное количество объектов в этом пуле объектов, и оттуда вы можете проверить, является ли это выделение, вызывающее эту ошибку, или если это что-то еще.

С 26-м элементом частота кадров снижается до 25 кадров в секунду.

Когда (или если) вы реализуете это, вы должны увидеть падение частоты кадров напрямую (если это не решит вашу проблему), поскольку пул объектов сделает вам выделение фиксированной суммы (например, может быть, 100 элементов?). (но вы не используете их визуально).

Кроме того, я использовал шаблон пула памяти (пул объектов) в одном из моих примерных приложений для Android. В этом образце; Я добавляю строку в Canvas на onTouchEvent(), используя пул объектов (без выделения во время выполнения). В этом исходном коде вы можете легко изменить общее количество объектов и проверить его и попробовать сами. Напишите комментарий, если вы хотите посмотреть мое примерное приложение (и исходный код), и я с удовольствием поделюсь им, так как он еще не открыт. Мои комментарии находятся в шведском, но я думаю, что вы должны понимать, поскольку переменные и методы находятся в английском.:)

Боковое примечание. Вы написали, что вы попытались (и даже успели) удалить это поведение, создав Bitmap static. Как сейчас, ваши элементы имеют разные экземпляры Bitmap, которые позволят вам выделять новый Bitmap каждый раз, когда вы создаете новый объект. Это означает, что каждый объект указывает на другой Bitmap, когда он использует один и тот же ресурс. static - полностью действующее решение (хотя магическое число из 25 кажется странным).

Этот случай Bitmap можно сравнить с системой OpenGL. Если у вас есть 20 объектов, все из которых должны использовать один и тот же ресурс, есть два возможных решения: они могут указывать на одну и ту же текстуру VRAM или либо они могут указывать на другую текстуру VRAM (например, ваш случай, когда вы не используете static), но все тот же ресурс.

ИЗМЕНИТЬ

Вот мое примерное приложение для Android, которое демонстрирует пул памяти.

Что касается вашего решения с BitmapFactory, это, вероятно, зависит от того, как работает этот класс. Я не уверен, но я думаю, что один из методов decode...() создает новый Bitmap, даже если он является одним и тем же ресурсом. Это может быть так, что new BufferedInputStream(res.openRawResource(R.drawable.icon)) повторно использует BufferedInputStream из памяти, хотя это большая догадка.

Что вы должны сделать (в этом случае) - это декодировать ресурс и сохранить ссылку из него в классе Panel и передать эту ссылку в new Element(bitmapReference, ...). Таким образом, вы выделяете его только один раз, и каждый элемент указывает на тот же Bitmap в памяти.

Ответ 2

Я пробовал свой код на HTC Desire HD, и частота кадров падает до непригодности после добавления 20-го изображения с использованием целевой Android 2.2. Когда я экспортировал тот же код, что и версия для Android 2.1, он работал нормально и мог обрабатывать более 200 экземпляров! Я подозреваю, что это связано с созданием экземпляров вашего класса GraphicObject на 2.2, но не совсем уверен...

Ответ 3

Я считаю, что могу пролить свет на эту проблему.

По крайней мере, на моей Галактике S, Gingerbread 2.3.5 первый код загружает мой test.png в Bitmap с Bitmap.Config = ARGB_8888, а второй код загружается с Bitmap.Config = RGB565. Странная вещь, в то время как Gingerbread по умолчанию должен создать 32-битную поверхность, RGB565 "рендерит" (я профилировал и сравнивал собственный вызов drawBitmap) намного быстрее.

Следовательно, вторая идея, более подходящая для вашего примера в целом, заключается в том, что битмаг ARGB888 имеет альфа, поэтому в этом случае рендеринг перекрывающихся изображений из 25+ спрайтов может создать узкое место в алгоритме альфа-вычисления, тогда как изображение RGB565 будет хорошо и быстро.