我正在制作动态壁纸(实际上是我的第一个 :)),我似乎陷入了僵局:
如果您还没有通过变量名和代码猜到的话,那么有问题的动态壁纸就是一个时钟。它的组件必须遵循非常严格的度数/时间比率(总共会有十几个位图以不同的速率、不同的方向旋转(一些遵循相同的比率/规则))。
无论如何...就目前而言,添加的每个额外位图几乎都会使 drawFrame() 的执行长度增加一倍。如果我要停在 3 个运动部件上,那还不错,看起来还可以;但是将位图数量增加 9 个(甚至增加 2 个或 3 个)并且帧速率变得不可接受。
我没有按照建议每回合重新解码位图...
我应该怎么做才能纠正这种情况?
我正在考虑研究 openGL 表面/引擎,但我在 SO 上看到了一个交换,其中用户一次处理 100 多个位图没有问题(Android drawBitmap Performance For lots of Bitmaps?),这让我希望我能做同样的事情.
我还在相应的可绘制 -_dpi 文件夹中包含了每个图像的适当版本。图像不是特别大,文件大小相当小,因为有很多颜色和很多透明部分(最大 = 屏幕尺寸,最小 = 90%widthscreen/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);
}