私はライブ壁紙に取り組んでいます (私の最初の実際:))、そして私は行き詰まりに達したようです:
変数名とコードから推測していない場合、問題のライブ壁紙は時計です。そのコンポーネントは、非常に厳密な角度/時間比率に従う必要があります (合計で、異なる速度で異なる方向に回転する 10 を超えるビットマップが存在します (一部は同じ比率/ルールに従います))。
とにかく...現状では、追加されるすべての追加のビットマップは、drawFrame() の実行の長さをほぼ 2 倍にします。3 つの可動部分で停止する場合は、それほど悪くはありません。このままで問題ありません。しかし、ビットマップの量を 9 (または 2 または 3 以上) 増やすと、フレーム レートが受け入れられなくなります。
推奨されているように、毎ターンビットマップを再デコードしていません...
この状況を改善するにはどうすればよいですか?
私はopenGLサーフェス/エンジンを調べようと考えていましたが、ユーザーが一度に100を超えるビットマップを問題なく処理しているSOの交換を見ました( Android drawBitmap Performance For Loose 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);
}