0

私はライブ壁紙に取り組んでいます (私の最初の実際:))、そして私は行き詰まりに達したようです:

変数名とコードから推測していない場合、問題のライブ壁紙は時計です。そのコンポーネントは、非常に厳密な角度/時間比率に従う必要があります (合計で、異なる速度で異なる方向に回転する 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);
    }
4

1 に答える 1

0

アニメーションには別のスレッドを使用することを検討してください。私が GitHub に投稿したライブ壁紙テンプレートを使用して、このソリューションを簡単にテストし、違いが生じるかどうかを確認できます。

于 2013-09-23T06:36:10.650 に答える