Android - 如何通过动画背景提高应用程序性能?

时间:2015-05-21 10:44:01

标签: android surfaceview

我有应用程序中所有屏幕的背景和动画。我有  使用表面视图和线程创建了动画背景。

下面  是我的SurfaceView班。

public class FloatingCirclesPanel extends SurfaceView implements
    SurfaceHolder.Callback {

    private static final String TAG = FloatingCirclesPanel.class
            .getSimpleName();

    public MainThread thread;
    private Circle circle_white1;

    private Circle circle_blue1;

    private Circle circle_white2;

    private Circle circle_blue2;

    private Bitmap scaled;
    Canvas canvas = null;

    private Display mdisp;

    private Context context;

    private RotateAnimation anim;

    private Matrix matrix;

    @SuppressLint("NewApi")
    public FloatingCirclesPanel(Context context) {
        super(context);
        this.context = context;
        matrix = new Matrix();
        // adding the callback (this) to the surface holder to intercept events
        getHolder().addCallback(this);

        // create droid and load bitmap
        circle_white1 = new Circle(BitmapFactory.decodeResource(getResources(),
                R.drawable.circle), 50, 50);
        mdisp = ((Activity) getContext()).getWindowManager()
                .getDefaultDisplay();
        Point mdispSize = new Point();
        mdisp.getSize(mdispSize);
        int maxX = mdispSize.x;
        int maxY = mdispSize.y;
        Bitmap b = scaleDown(BitmapFactory.decodeResource(getResources(),
                R.drawable.circle_img), 300, true);
        Bitmap b1 = scaleDown(BitmapFactory.decodeResource(getResources(),
                R.drawable.circle_img), 130, true);
        Bitmap b2 = scaleDown(
                BitmapFactory.decodeResource(getResources(), R.drawable.circle),
                100, true);
        // droid1 = new Droid(BitmapFactory.decodeResource(getResources(),
        // R.drawable.icon), 150, 150);
        if (b != null) {
            circle_blue1 = new Circle(b, 500, 500);
        } else {
            circle_blue1 = new Circle(BitmapFactory.decodeResource(
                    getResources(), R.drawable.circle_img), 500, 500);
        }
        if (b1 != null) {
            circle_white2 = new Circle(b1, 800, 800);
        } else {
            circle_white2 = new Circle(BitmapFactory.decodeResource(
                    getResources(), R.drawable.circle), 800, 800);
        }
        if (b2 != null) {
            circle_blue2 = new Circle(b2, 1500, 1500);
        } else {
            circle_blue2 = new Circle(BitmapFactory.decodeResource(
                    getResources(), R.drawable.circle_img), 1500, 1500);
        }
        // droid3 = new Droid(BitmapFactory.decodeResource(getResources(),
        // R.drawable.icon), 150, 150);

        // create the game loop thread
        thread = new MainThread(getHolder(), this, context);

        // make the GamePanel focusable so it can handle events
        setFocusable(true);
    }

    public FloatingCirclesPanel(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    public FloatingCirclesPanel(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
    }

    public static Bitmap scaleDown(Bitmap realImage, float maxImageSize,
            boolean filter) {
        float ratio = Math.min((float) maxImageSize / realImage.getWidth(),
                (float) maxImageSize / realImage.getHeight());
        int width = Math.round((float) ratio * realImage.getWidth());
        int height = Math.round((float) ratio * realImage.getHeight());

        Bitmap newBitmap = Bitmap.createScaledBitmap(realImage, width, height,
                filter);
        return newBitmap;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // at this point the surface is created and
        // we can safely start the game loop
        if (thread != null && (thread.getState() == Thread.State.NEW)) {
            thread.setRunning(true);// riga originale
            thread.start();// riga originale
        }

        // after a pause it starts the thread again
        else if (thread != null && thread.getState() == Thread.State.TERMINATED) {
            thread = new MainThread(getHolder(), this, context);
            ;
            thread.setRunning(true);
            thread.start(); // Start a new thread
        }
        // thread.setRunning(true);
        // thread.start();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.d(TAG, "Surface is being destroyed");
        // tell the thread to shut down and wait for it to finish
        // this is a clean shutdown
        boolean retry = true;
        while (retry) {
            try {
                thread.interrupt();
                retry = false;
                thread = null;
            } catch (Exception e) {
                // try again shutting down the thread
            }
        }
        Log.d(TAG, "Thread was shut down cleanly");
    }

    public void render(Canvas canvas) {
        if (canvas != null) {
            Rect dest = new Rect(0, 0, getWidth(), getHeight());
            Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
            paint.setFilterBitmap(true);
            paint.setDither(true);
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
                    R.drawable.splashscreen);
            canvas.drawBitmap(bitmap, null, dest, paint);

            // canvas.drawColor(Color.BLUE);
            circle_white1.draw(canvas);
            circle_blue1.draw(canvas);
            circle_white2.draw(canvas);
            circle_blue2.draw(canvas);

        }

    }

    private void createAnimation(Canvas canvas) {
        anim = new RotateAnimation(0, 360, getWidth() / 2, getHeight() / 2);
        anim.setRepeatMode(Animation.RESTART);
        anim.setRepeatCount(Animation.INFINITE);
        anim.setDuration(10000L);
        ((Activity) context).runOnUiThread(new Runnable() {
            @Override
            public void run() {

                startAnimation(anim);

            }
        });

    }

    /**
     * This is the game update method. It iterates through all the objects and
     * calls their update method if they have one or calls specific engine's
     * update method.
     */
    public void update() {
        // check collision with right wall if heading right
        if (circle_white1.getSpeed().getxDirection() == Speed.DIRECTION_RIGHT
                && circle_white1.getX() + circle_white1.getBitmap().getWidth()
                        / 2 >= getWidth()) {
            circle_white1.getSpeed().toggleXDirection();
        }
        // check collision with left wall if heading left
        if (circle_white1.getSpeed().getxDirection() == Speed.DIRECTION_LEFT
                && circle_white1.getX() - circle_white1.getBitmap().getWidth()
                        / 2 <= 0) {
            circle_white1.getSpeed().toggleXDirection();
        }
        // check collision with bottom wall if heading down
        if (circle_white1.getSpeed().getyDirection() == Speed.DIRECTION_DOWN
                && circle_white1.getY() + circle_white1.getBitmap().getHeight()
                        / 2 >= getHeight()) {
            circle_white1.getSpeed().toggleYDirection();
        }
        // check collision with top wall if heading up
        if (circle_white1.getSpeed().getyDirection() == Speed.DIRECTION_UP
                && circle_white1.getY() - circle_white1.getBitmap().getHeight()
                        / 2 <= 0) {
            circle_white1.getSpeed().toggleYDirection();
        }
        // Update the lone droid
        circle_white1.update();
        if (circle_blue1.getSpeed().getxDirection() == Speed.DIRECTION_RIGHT
                && circle_blue1.getX() + circle_blue1.getBitmap().getWidth()
                        / 2 >= getWidth()) {
            circle_blue1.getSpeed().toggleXDirection();
        }
        // check collision with left wall if heading left
        if (circle_blue1.getSpeed().getxDirection() == Speed.DIRECTION_LEFT
                && circle_blue1.getX() - circle_blue1.getBitmap().getWidth()
                        / 2 <= 0) {
            circle_blue1.getSpeed().toggleXDirection();
        }
        // check collision with bottom wall if heading down
        if (circle_blue1.getSpeed().getyDirection() == Speed.DIRECTION_DOWN
                && circle_blue1.getY() + circle_blue1.getBitmap().getHeight()
                        / 2 >= getHeight()) {
            circle_blue1.getSpeed().toggleYDirection();
        }
        // check collision with top wall if heading up
        if (circle_blue1.getSpeed().getyDirection() == Speed.DIRECTION_UP
                && circle_blue1.getY() - circle_blue1.getBitmap().getHeight()
                        / 2 <= 0) {
            circle_blue1.getSpeed().toggleYDirection();
        }
        // Update the lone droid1
        circle_blue1.update();
        if (circle_white2.getSpeed().getxDirection() == Speed.DIRECTION_RIGHT
                && circle_white2.getX() + circle_white2.getBitmap().getWidth()
                        / 2 >= getWidth()) {
            circle_white2.getSpeed().toggleXDirection();
        }
        // check collision with left wall if heading left
        if (circle_white2.getSpeed().getxDirection() == Speed.DIRECTION_LEFT
                && circle_white2.getX() - circle_white2.getBitmap().getWidth()
                        / 2 <= 0) {
            circle_white2.getSpeed().toggleXDirection();
        }
        // check collision with bottom wall if heading down
        if (circle_white2.getSpeed().getyDirection() == Speed.DIRECTION_DOWN
                && circle_white2.getY() + circle_white2.getBitmap().getHeight()
                        / 2 >= getHeight()) {
            circle_white2.getSpeed().toggleYDirection();
        }
        // check collision with top wall if heading up
        if (circle_white2.getSpeed().getyDirection() == Speed.DIRECTION_UP
                && circle_white2.getY() - circle_white2.getBitmap().getHeight()
                        / 2 <= 0) {
            circle_white2.getSpeed().toggleYDirection();
        }
        // Update the lone droid2
        circle_white2.update();
        if (circle_blue2.getSpeed().getxDirection() == Speed.DIRECTION_RIGHT
                && circle_blue2.getX() + circle_blue2.getBitmap().getWidth()
                        / 2 >= getWidth()) {
            circle_blue2.getSpeed().toggleXDirection();
        }
        // check collision with left wall if heading left
        if (circle_blue2.getSpeed().getxDirection() == Speed.DIRECTION_LEFT
                && circle_blue2.getX() - circle_blue2.getBitmap().getWidth()
                        / 2 <= 0) {
            circle_blue2.getSpeed().toggleXDirection();
        }
        // check collision with bottom wall if heading down
        if (circle_blue2.getSpeed().getyDirection() == Speed.DIRECTION_DOWN
                && circle_blue2.getY() + circle_blue2.getBitmap().getHeight()
                        / 2 >= getHeight()) {
            circle_blue2.getSpeed().toggleYDirection();
        }
        // check collision with top wall if heading up
        if (circle_blue2.getSpeed().getyDirection() == Speed.DIRECTION_UP
                && circle_blue2.getY() - circle_blue2.getBitmap().getHeight()
                        / 2 <= 0) {
            circle_blue2.getSpeed().toggleYDirection();
        }
        // Update the lone droid3
        circle_blue2.update();
    }

}

我将SurfaceView添加到我的活动中,如下所示

@Override
protected void onStart() {
    super.onStart();
View childView = getLayoutInflater().inflate(R.layout.main, null);
    circleAnimation = new FloatingCirclesPanel(this);
    setContentView(circleAnimation);
    final ImageView image = (ImageView) childView.findViewById(R.id.logout);

现在问题是应用程序在浏览应用程序中的屏幕时运行缓慢。

如果我在onStart / onResume中添加了SurfaceView代码,则整个视图会重新设计两次并导致性能问题。

如何改善表现?

0 个答案:

没有答案