在事件和位图中进行预分配

3
我正在为Android编写一个游戏,每隔几秒钟就会出现明显的暂停,这是由于GC运行所导致的。我已将分配降至最低,并且Allocation Tracker显示的仅剩下Bitmap.createBitmap(..)onTouchEventonKeyEvent的分配。每帧调用两次Bitmap.createBitmap(..),无法删除。
现在我的问题是:是否有其他方式来读取事件和创建位图?或者预先分配所需的操作内存并告诉它们使用它?
InputHandler类(包含监听器):
public class InputHandler {

private ISwarmInput mGame;

// Declare input types
public static final int USE_TOUCH = 0;
public static final int USE_MOTION = 1;
public static final int USE_KEY = 2;
public static final int USE_TOUCH_AND_KEY = 3;

private int mInputType;
public OrientationEventListener mOrientationListener;
public OnTouchListener mTouchListener;
public OnKeyListener mKeyListener;

public InputHandler(Context context, ISwarmInput game) {
    mGame = game;
    mTouchListener = createTouchListener();
    mKeyListener = createKeyListener();
}

public OrientationEventListener createTiltListener(Context context) {
    return new OrientationEventListener(context) {
        @Override
        public void onOrientationChanged(int orientation) {
            if (mInputType == USE_MOTION) {
                mGame.setAngle(orientation);
            }
        }
    };
}

public OnTouchListener createTouchListener() {
    return new OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event){
            if (mInputType == USE_TOUCH || mInputType == USE_TOUCH_AND_KEY) {
                if (readPointIn(event.getX(), event.getY())) {
                    mGame.addNewPoint((int) event.getX(),
                            (int) event.getY());
                }
            }
            return true;
        }
    };
}

public OnKeyListener createKeyListener() {
    return new OnKeyListener() {
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (mInputType == USE_KEY || mInputType == USE_TOUCH_AND_KEY) {
                switch (keyCode) {
                case KeyEvent.KEYCODE_DPAD_UP:
                    mGame.setAngle(-90);
                    break;
                case KeyEvent.KEYCODE_DPAD_LEFT:
                    mGame.setAngle(180);
                    break;
                case KeyEvent.KEYCODE_DPAD_DOWN:
                    mGame.setAngle(90);
                    break;
                case KeyEvent.KEYCODE_DPAD_RIGHT:
                    mGame.setAngle(0);
                    break;
                }
            }
            return false;
        }
    };
}
}

位图创建部分

public void drawHead(Canvas canv) {
    mat.reset();
    nextFrame();

    setRotationAndFlip(mat);

    this.bmp = Bitmap.createBitmap(SPRITESHEET, Bird.mCurFrame * BIG_W[mUseBird], 0,
            BIG_W[mUseBird], BIG_H[mUseBird], mat, true);
    super.drawPlaceable(canv);

    mat.preScale((float)0.6, (float)0.6);
    this.bmp = Bitmap.createBitmap(SPRITESHEET, Bird.mCurFrame * BIG_W[mUseBird], 0,
            BIG_W[mUseBird], BIG_H[mUseBird], mat, true);
}

这个游戏类似于贪吃蛇,你是一只鸟,每吃掉一条虫子,就会有一只更小的鸟跟随在你后面。第二个位图是用来表示跟随的小鸟的。


是的,你需要预先分配和重复使用它们。如果你想要建议,你可能想展示你当前的实现。 - mibollma
@mibollma:完成了。那么,我该如何预先分配并重复使用它? - SBoss
1个回答

0

谢谢提供链接,我会仔细查看。使用相同大小的精灵如何有所帮助?分配(用于画布、绘画和位图)是在Bitmap.createBitmap(..)内部代码中进行的。 - SBoss
你说得对,在你的情况下这并没有什么帮助。所以我猜你的替代方案是创建一堆不同的旋转,比如每5°一个步骤,或者使用Canvas.rotate()(这也很慢)。 - mibollma
我意识到问题不在于事件,但是无法解决位图的问题。感谢您的帮助。 - SBoss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接