Я работаю над живыми обоями (мой первый на самом деле :)), и я, похоже, зашел в тупик:Вращение нескольких растровых изображений на холсте, проект живых обоев; почему каждый дополнительный битмап замедляет каждый drawFrame()? (код включен!)
Если вы не догадались, что это имена переменных и код , живые обои в вопросе - часы. Его компоненты должны следовать очень строгому соотношению градусов/времени (в общей сложности будет более десятка растровых изображений, вращающихся с разной скоростью, в разных направлениях (некоторые из них соответствуют тем же соотношениям/правилам)).
Anyways ... Как бы то ни было, каждое добавочное растровое изображение, которое добавлено, почти удваивает длину выполнения drawFrame(). Если бы я остановился на 3 движущихся частях, это было бы не так плохо, это выглядит нормально, как есть; но увеличьте количество битмапов на 9 (или даже на 2 или 3 больше), и частота кадров станет неприемлемой.
Я не повторно декодирования растровых изображений каждый поворот, как рекомендуется ...
Что я должен сделать, чтобы исправить эту ситуацию?
Я думал о том, чтобы посмотреть в openGL поверхность/движок, но я видел обмен на SO, где пользователь обрабатывал более 100 растровых изображений сразу без проблем (Android drawBitmap Performance For Lots of Bitmaps?), что заставило меня надеяться, что смогу сделать то же самое.
Я также включил соответствующую версию каждого изображения в соответствующие палитры -_dpi. Изображения не особо велики, размер файла довольно мал, так как есть очень много цветов и много прозрачных частей (наибольший - размер экрана, наименьший = 90% ширина экрана/высота экрана 50% - поэтому для xhdpi 720 1280 самый большой и 565 * 562 наименьший)
Так что в основном, согласно моим исследованиям, мой код должен быть быстрым ... но это не так. Ясно, что я ошибаюсь :), пожалуйста, помогите мне понять это правильно!
спасибо.
void drawFrame()
{
timeSinceLastRun = AnimationUtils.currentAnimationTimeMillis() - timeAtLastRun;
timeAtLastRun = AnimationUtils.currentAnimationTimeMillis();
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try
{
c = holder.lockCanvas();
if (c != null)
{
c.save();
c.drawColor(0xff000000);
drawTouchPoint(c);
if(isItPhase1)
{
skipToPosition(c,0,0,false,1);
skipToPosition(c,1,1,false,2);
skipToPosition(c,2,2,true,3);
}
else
{
animateGears(c,0,0,0,0);
animateGears(c,1,1,1,1);
animateGears(c,2,2,2,2);
}
c.restore();
}
}
finally
{
if (c != null)
holder.unlockCanvasAndPost(c);
}
mHandler.removeCallbacks(mDrawPattern);
if (mVisible)
{
mHandler.postDelayed(mDrawPattern, 1000/25);
}
}
private void skipToPosition(Canvas c, int xP, int yP, boolean lastTest, int timeBasis)
{
if(isItFirstRun)
{
gears[0] = BitmapFactory.decodeResource(getResources(),
l.werner.mechanicalclocklivewallpaperversion0001.R.drawable.seconds_gear);
gears[1] = BitmapFactory.decodeResource(getResources(),
l.werner.mechanicalclocklivewallpaperversion0001.R.drawable.minutes_gear);
gears[2] = BitmapFactory.decodeResource(getResources(),
l.werner.mechanicalclocklivewallpaperversion0001.R.drawable.hours_gear);
m[0] = new Matrix();
m[1] = new Matrix();
m[2] = new Matrix();
m2[0] = new Matrix();
m2[1] = new Matrix();
m2[2] = new Matrix();
x[0] = 0;
x[1] = 0;
x[2] = 0;
y[0] = 0.006f;
y[1] = 0.0001f;
y[2] = (0.000001666666666666666666666666666666667f);
timeSinceLastRun = 0;
movementPerTurn = 0;
isItFirstRun = !isItFirstRun;
}
Calendar cal = Calendar.getInstance();
float second = cal.get(Calendar.SECOND);
float minute = cal.get(Calendar.MINUTE);
float hour = cal.get(Calendar.HOUR);
if(timeBasis == 1)
x[xP] = x[xP] + (360f*(second/60f));
else if(timeBasis == 2)
x[xP] = x[xP] + (360f*(minute/60f));
else if(timeBasis == 3)
x[xP] = x[xP] + (360f*(hour/12f));
if(lastTest)
{
isItPhase1 = !isItPhase1;
}
}
void animateGears(Canvas c, int xP, int yP, int g, int mP)
{
movementPerTurn = y[yP] * timeSinceLastRun;
x[xP] = x[xP] + movementPerTurn;
m[mP].setRotate(((float)x[xP]*1f), 0.5f*gears[g].getWidth(),0.5f*gears[g].getHeight());
m2[mP].setTranslate(c.getWidth()/2f - 0.5f*gears[g].getWidth(),
c.getHeight()/2f - 0.5f*gears[g].getHeight());
m[mP].setConcat(m2[mP], m[mP]);
c.drawBitmap(gears[g], m[mP] , null);
}