Android SurfaceView onTouchEvent未被调用

时间:2016-04-25 05:20:42

标签: android canvas surfaceview ontouchevent

我正在使用SurfaceView开发游戏,该游戏可以监听触摸事件。 SurfaceView中的onTouchEvent方法适用于许多设备,但在某些设备中,有时它不会被调用(Moto X Style就是那个),我的应用程序也停止响应。

我想这可能是由于onTouchEvent正在挨饿导致主线程超载。

这里的一些Android专家可以给我一些提示,以减少主线程的负载,如果它过载,或者可能有其他原因导致这个

代码非常复杂,但如果您想要通过它,我仍然会发布一些代码

GameLoopThread

public class GameLoopThread extends Thread{
    private GameView view;
    // desired fps
    private final static int    MAX_FPS = 120;
    // maximum number of frames to be skipped
    private final static int    MAX_FRAME_SKIPS = 5;
    // the frame period
    private final static int    FRAME_PERIOD = 1000 / MAX_FPS;

    private boolean running = false;

    public GameLoopThread(GameView view){
        this.view = view;
    }

    public void setRunning(boolean running){
        this.running = running;
    }

    public boolean isRunning() {
        return running;
    }
    @Override
    public void run() {
        Canvas canvas;
        long beginTime;     // the time when the cycle begun
        long timeDiff;      // the time it took for the cycle to execute
        int sleepTime;      // ms to sleep (<0 if we're behind)
        int framesSkipped;  // number of frames being skipped

        while (running) {
            canvas = null;
            // try locking the canvas for exclusive pixel editing
            // in the surface
            try {
                canvas = view.getHolder().lockCanvas();
                synchronized (view.getHolder()) {
                    beginTime = System.nanoTime();
                    framesSkipped = 0;  // resetting the frames skipped
                    // update game state
                    // render state to the screen
                    // draws the canvas on the panel
                    this.view.draw(canvas);
                    // calculate how long did the cycle take
                    timeDiff = System.nanoTime() - beginTime;
                    // calculate sleep time
                    sleepTime = (int)(FRAME_PERIOD - timeDiff/1000000);

                    if (sleepTime > 0) {
                        // if sleepTime > 0 we're OK
                        try {
                            // send the thread to sleep for a short period
                            // very useful for battery saving
                            Thread.sleep(sleepTime);
                        } catch (InterruptedException e) {}
                    }

                    while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
                        // update without rendering
                        // add frame period to check if in next frame
                        sleepTime += FRAME_PERIOD;
                        framesSkipped++;
                    }
                }
            }
            finally {
                // in case of an exception the surface is not left in
                // an inconsistent state
                view.getHolder().unlockCanvasAndPost(canvas);
            }   // end finally
        }
    }
}

GameView

public class GameView extends SurfaceView {
    ArrayList<Bitmap> circles = new ArrayList<>();
    int color;
    public static boolean isGameOver;

    public GameLoopThread gameLoopThread;
    Circle circle;      // Code for Circle class is provided below

    public static int score = 0;
    public static int stars = 0;

    final Handler handler = new Handler();

    int remainingTime;

    boolean oneTimeFlag;

    Bitmap replay;
    Bitmap home;
    Bitmap star;

    int highScore;
    boolean isLeaving;

    public GameView(Context context, ArrayList<Bitmap> circles, int color) {
        super(context);
        this.circles = circles;
        this.color = color;

        oneTimeFlag = true;
        gameLoopThread = new GameLoopThread(GameView.this);

        getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                if (!gameLoopThread.isRunning()) {
                    gameLoopThread.setRunning(true);
                    gameLoopThread.start();
                }
            }

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

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                gameLoopThread.setRunning(false);
                gameLoopThread = new GameLoopThread(GameView.this);
            }
        });

        initializeCircles();
        if(!gameLoopThread.isRunning()) {
            gameLoopThread.setRunning(true);
            gameLoopThread.start();
        }
    }

    public void initializeCircles() {
        ArrayList<String> numbers = new ArrayList<>();
        for(int i=0;i<10;i++)
            numbers.add(i+"");

        Random random = new Random();
        int position = random.nextInt(4);
        numbers.remove(color + "");

        int p1 = position;

        int r1 = Integer.valueOf(numbers.get(random.nextInt(9)));
        numbers.remove(r1+"");

        int r2 = Integer.valueOf(numbers.get(random.nextInt(8)));
        numbers.remove(r2 + "");

        int r3 = Integer.valueOf(numbers.get(random.nextInt(7)));

        ArrayList<Bitmap> bitmaps = new ArrayList<>();

        if(position == 0) {
            bitmaps.add(circles.get(color));
            bitmaps.add(circles.get(r1));
            bitmaps.add(circles.get(r2));
            bitmaps.add(circles.get(r3));
        }
        else if(position == 1) {
            bitmaps.add(circles.get(r1));
            bitmaps.add(circles.get(color));
            bitmaps.add(circles.get(r2));
            bitmaps.add(circles.get(r3));
        }
        else if(position == 2) {
            bitmaps.add(circles.get(r1));
            bitmaps.add(circles.get(r2));
            bitmaps.add(circles.get(color));
            bitmaps.add(circles.get(r3));
        }
        else {
            bitmaps.add(circles.get(r1));
            bitmaps.add(circles.get(r2));
            bitmaps.add(circles.get(r3));
            bitmaps.add(circles.get(color));
        }

        numbers = new ArrayList<>();
        for(int i=0;i<10;i++)
            numbers.add(i+"");

        position = random.nextInt(4);
        numbers.remove(color + "");

        r1 = Integer.valueOf(numbers.get(random.nextInt(9)));
        numbers.remove(r1 + "");

        r2 = Integer.valueOf(numbers.get(random.nextInt(8)));
        numbers.remove(r2 + "");

        r3 = Integer.valueOf(numbers.get(random.nextInt(7)));

        if(position == 0) {
            bitmaps.add(circles.get(color));
            bitmaps.add(circles.get(r1));
            bitmaps.add(circles.get(r2));
            bitmaps.add(circles.get(r3));
        }
        else if(position == 1) {
            bitmaps.add(circles.get(r1));
            bitmaps.add(circles.get(color));
            bitmaps.add(circles.get(r2));
            bitmaps.add(circles.get(r3));
        }
        else if(position == 2) {
            bitmaps.add(circles.get(r1));
            bitmaps.add(circles.get(r2));
            bitmaps.add(circles.get(color));
            bitmaps.add(circles.get(r3));
        }
        else {
            bitmaps.add(circles.get(r1));
            bitmaps.add(circles.get(r2));
            bitmaps.add(circles.get(r3));
            bitmaps.add(circles.get(color));
        }

        circle = new Circle(this, bitmaps, circles, p1, position, color, getContext());
    }

    @Override
    public void draw(Canvas canvas) {
        if(canvas != null) {
            super.draw(canvas);
            canvas.drawColor(Color.WHITE);

            if(!isGameOver && timer != null)
                stopTimerTask();
            try {
                circle.draw(canvas);
            } catch (GameOverException e) {
                isGameOver = true;
                if(isLeaving)
                    gameOver(canvas);
                else if(GameActivity.counter > 0) {
                    gameOver(canvas);
                    GameActivity.counter++;
                } else {
                    if (oneTimeFlag) {
                        int size1 = 200 * GameActivity.SCREEN_HEIGHT / 1280;
                        int size2 = 125 * GameActivity.SCREEN_HEIGHT / 1280;
                        float ratio = (float) GameActivity.SCREEN_HEIGHT / 1280;

                        replay = GameActivity.decodeSampledBitmapFromResource(getResources(), R.drawable.replay, size1, size1);
                        home = GameActivity.decodeSampledBitmapFromResource(getResources(), R.drawable.home, size2, size2);
                        continueButton = GameActivity.decodeSampledBitmapFromResource(getContext().getResources(), R.drawable.button, (int) (540 * ratio), (int) (100 * ratio));
                        star = GameActivity.decodeSampledBitmapFromResource(getContext().getResources(), R.drawable.star1, (int) (220 * ratio), (int) (220 * ratio));

                        int w = (int) ((float) GameActivity.SCREEN_WIDTH * 0.9);
                        oneTimeFlag = false;
                    }

                    if (askPurchaseScreen == 2) {
                        gameOver(canvas);
                    } else {
                        canvas.drawColor(Circle.endColor);
                    }
                }
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        circle.onTouch(x, y);
        return true;
    }
}

public class Circle {
    int x;
    int y1;
    int y2;
    public static float speedY1 = 12.5f*(float)GameActivity.SCREEN_HEIGHT/1280;
    public static float speedY2 = 12.5f*(float)GameActivity.SCREEN_HEIGHT/1280;
    ArrayList<Bitmap> bitmaps;
    GameView gameView;
    int p1;     // Position of required circle in slot 1
    int p2;     // Position of required circle in slot 2
    int color;
    int tempColor;
    int width;
    Context context;

    // Centers of required circle
    float centerX1;
    float centerX2;
    float centerY1;
    float centerY2;

    ArrayList<Bitmap> circles = new ArrayList<>();
    boolean touchedFirst;
    boolean touchedSecond;
    int count1 = 1;     // Slot 1 circle radius animation
    int count2 = 1;     // Slot 2 circle radius animation

    float tempSpeedY1;
    float tempSpeedY2;
    boolean stopY1;
    boolean stopY2;
    int barCounter = 1;
    int loopCount = 0;

    int endGameCount = 0;   // Count to move circle upwards
    double limit;
    float endRadiusSpeed;
    int endSlot;    // Where you died
    int endRadiusCount = 0; // Count to increase circle radius
    int barEndCounter = 1;

    final Handler handler = new Handler();
    boolean exception;
    public static int endColor;

    public Circle(GameView gameView, ArrayList<Bitmap> bitmaps, ArrayList<Bitmap> circles, int p1, int p2, int color, Context context) {
        this.gameView = gameView;
        this.bitmaps = bitmaps;
        this.circles = circles;
        this.p1 = p1;
        this.p2 = p2;
        this.color = color;
        this.context = context;

        width = GameActivity.SCREEN_WIDTH / 4 - 10;
        x = 10;
        y1 = 0;
        y2 = -(GameActivity.SCREEN_HEIGHT + width) / 2;

        centerX1 = x + p1 * (10 + width) + width / 2;
        centerY1 = y1 + width / 2;

        centerX2 = x + p2 * (10 + width) + width / 2;
        centerY2 = y2 + width / 2;
    }

    public void update() throws GameOverException {
        y1+= speedY1;
        y2+= speedY2;

        centerY1+= speedY1;
        centerY2+= speedY2;

        float ratio = (float)GameActivity.SCREEN_HEIGHT/1280;
        limit = width/(20*ratio);

        if(y1 >= gameView.getHeight()) {
            loopCount++;

            if(touchedFirst)
                touchedFirst = false;
            else {
                speedY1 = speedY2 = -(12.5f * ratio);
                endColor = bitmaps.get(p1).getPixel(width/2, width/2);

                endGameCount += 1;
                endSlot = 1;
            }

            if(endGameCount == 0) {
                if (stopY1) {
                    tempSpeedY1 = speedY1;
                    speedY1 = 0;
                    ArrayList<Integer> numbers = new ArrayList<>();
                    for (int i = 0; i < 10; i++) {
                        if (i != color)
                            numbers.add(i);
                    }
                    tempColor = numbers.get(new Random().nextInt(9));
                }

                y1 = -(gameView.getWidth() / 4 - 10);
                count1 = 1;
                setBitmaps(1);
            }
        }
        else if(y2 >= gameView.getHeight()) {
            loopCount++;

            if(touchedSecond)
                touchedSecond = false;
            else {
                speedY1 = speedY2 = -(12.5f * ratio);
                endColor = bitmaps.get(p2 + 4
                ).getPixel(width/2, width/2);
                endGameCount += 1;
                endSlot = 2;
            }

            if(endGameCount == 0) {
                if (stopY2) {
                    tempSpeedY2 = speedY2;
                    speedY2 = 0;
                }

                y2 = -(gameView.getWidth() / 4 - 10);
                count2 = 1;
                setBitmaps(2);
            }
        }
    }

    public void setBitmaps(int slot) {
        ArrayList<String> numbers = new ArrayList<>();
        for(int i=0;i<10;i++)
            numbers.add(i+"");

        Random random = new Random();
        int position = random.nextInt(4);
        numbers.remove(color + "");

        int r1 = Integer.valueOf(numbers.get(random.nextInt(9)));
        numbers.remove(r1+"");

        int r2 = Integer.valueOf(numbers.get(random.nextInt(8)));
        numbers.remove(r2 + "");

        int r3 = Integer.valueOf(numbers.get(random.nextInt(7)));

        if(position == 0) {
            bitmaps.set((slot - 1)*4, circles.get(color));
            bitmaps.set((slot - 1)*4 + 1, circles.get(r1));
            bitmaps.set((slot - 1)*4 + 2, circles.get(r2));
            bitmaps.set((slot - 1)*4 + 3, circles.get(r3));
        }
        else if(position == 1) {
            bitmaps.set((slot - 1)*4, circles.get(r1));
            bitmaps.set((slot - 1)*4 + 1, circles.get(color));
            bitmaps.set((slot - 1)*4 + 2, circles.get(r2));
            bitmaps.set((slot - 1)*4 + 3, circles.get(r3));
        }
        else if(position == 2) {
            bitmaps.set((slot - 1)*4, circles.get(r1));
            bitmaps.set((slot - 1)*4 + 1, circles.get(r2));
            bitmaps.set((slot - 1)*4 + 2, circles.get(color));
            bitmaps.set((slot - 1)*4 + 3, circles.get(r3));
        } else {
            bitmaps.set((slot - 1)*4,circles.get(r1));
            bitmaps.set((slot - 1)*4 + 1,circles.get(r2));
            bitmaps.set((slot - 1)*4 + 2,circles.get(r3));
            bitmaps.set((slot - 1)*4 + 3,circles.get(color));
        }
        if(slot == 1) {
            p1 = position;
            centerX1 = x+position*(10 + width) + width/2;
            centerY1 = y1 + width/2;
        }
        else if(slot == 2) {
            p2 = position;
            centerX2 = x+position*(10 + width) + width/2;
            centerY2 = y2 + width/2;
        }
    }

    public void onTouch(float X, float Y) {
        int radius = (gameView.getWidth() / 4 - 10) / 2;

        if(endGameCount == 0) {
            if ((X >= centerX1 - radius) && (X <= centerX1 + radius) && (Y >= centerY1 - radius) && (Y <= centerY1 + radius)) {
                GameView.score++;
                touchedFirst = true;
                centerX1 = centerY1 = -1;

                if(p1 == (timerCount - 1) && timer != null && starSlot == 1) {
                    GameView.stars++;
                    starCollected = true;
                    timerCount = 0;
                    stopTimerTask(0);
                }
            } else if ((X >= centerX2 - radius) && (X <= centerX2 + radius) && (Y >= centerY2 - radius) && (Y <= centerY2 + radius)) {
                GameView.score++;
                touchedSecond = true;
                centerX2 = centerY2 = -1;

                if(p2 == (timerCount - 1) && timer != null && starSlot == 2) {
                    GameView.stars++;
                    starCollected = true;
                    timerCount = 0;
                    stopTimerTask(0);
                }
            } else {
                endSlot = 0;
                if ((Y >= centerY1 - radius) && (Y <= centerY1 + radius)) {
                    endSlot = 1;
                    if (X >= 10 && X <= 10 + 2 * radius) {
                        p1 = 0;
                        centerX1 = 10 + radius;
                    } else if (X >= 20 + 2 * radius && X <= 20 + 4 * radius) {
                        p1 = 1;
                        centerX1 = 20 + 3 * radius;
                    } else if (X >= 30 + 4 * radius && X <= 30 + 6 * radius) {
                        p1 = 2;
                        centerX1 = 30 + 5 * radius;
                    } else if (X >= 40 + 6 * radius && X <= 40 + 8 * radius) {
                        p1 = 3;
                        centerX1 = 40 + 2 * radius;
                    } else
                        endSlot = 0;
                } else if ((Y >= centerY2 - radius) && (Y <= centerY2 + radius)) {
                    endSlot = 2;
                    if (X >= 10 && X <= 10 + 2 * radius) {
                        p2 = 0;
                        centerX2 = 10 + radius;
                    } else if (X >= 20 + 2 * radius && X <= 20 + 4 * radius) {
                        p2 = 1;
                        centerX2 = 20 + 3 * radius;
                    } else if (X >= 30 + 4 * radius && X <= 30 + 6 * radius) {
                        p2 = 2;
                        centerX2 = 30 + 5 * radius;
                    } else if (X >= 40 + 6 * radius && X <= 40 + 8 * radius) {
                        p2 = 3;
                        centerX2 = 40 + 2 * radius;
                    } else
                        endSlot = 0;
                }
                if (endSlot != 0) {
                    speedY1 = speedY2 = 0;
                    limit = endGameCount = 6;

                    if (endSlot == 1) {
                        endColor= bitmaps.get(p1).getPixel(width/2, width/2);
                    } else {
                        endColor = bitmaps.get(p2 + 4).getPixel(width/2, width/2);
                    }
                }
            }

            if (GameView.score % 5 == 0 && GameView.score <= 110 && barCounter == 1) {
                float ratio = (float)GameActivity.SCREEN_HEIGHT/1280;
                speedY1 += ratio*0.5;
                speedY2 += ratio*0.5;
            }

            if (GameView.score > 0 && GameView.score % 15 == 14) {
                if(isOddScore)
                    stopY1 = true;
                else
                    stopY2 = true;
            }

            if (GameView.score > 0 && GameView.score % 15 == 0 && barCounter == 1) {
                if(isOddScore)
                    stopY2 = true;
                else
                    stopY1 = true;
            }

            if (GameView.score % 15 == 1)
                barCounter = 1;
        }
    }
    public void draw(Canvas canvas) throws GameOverException {
        GameView.isGameOver = false;
        if(exception)
            throw new GameOverException(color);
        update();

        for(int i=0;i<bitmaps.size();i++) {
            if(i<4) {
                Rect rect = new Rect(x+i*(10 + width),y1,(x+width)*(i+1),y1+width);
                if(endGameCount == Math.ceil(limit) && endSlot == 1) {
                    if(i == p1) {
                        endRadiusCount += 1;
                        if (endRadiusCount > 23) {
                            star.recycle();
                            loopCount = loopCount%starInterval;
                            Cryptography.saveFile((loopCount + "").getBytes(), context, "interval");
                            endGameCount = 0;
                            exception = true;
                            throw new GameOverException(color);
                        }

                        rect = new Rect(x + i * (10 + width) - endRadiusCount*(int)Math.ceil(endRadiusSpeed), y1 - endRadiusCount*(int)Math.ceil(endRadiusSpeed), (x + width) * (i + 1) + endRadiusCount*(int)Math.ceil(endRadiusSpeed), y1 + width + endRadiusCount*(int)Math.ceil(endRadiusSpeed));
                        canvas.drawBitmap(bitmaps.get(i), null, rect, null);
                    }
                }

                // TOUCH ANIMATION : DIMINISH CIRCLE
                else if(i==p1 && touchedFirst) {
                    rect = new Rect(x + i * (10 + width) + 3*count1 + ((int)speedY1-15), y1 + 3*count1 + ((int)speedY1-15), (x + width) * (i + 1) - 3*count1 - ((int)speedY1-15), y1 + width - 3*count1 - ((int)speedY1-15));
                    canvas.drawBitmap(bitmaps.get(i), null, rect, null);
                    count1++;
                }

                else if(endSlot != 2) {
                    canvas.drawBitmap(bitmaps.get(i), null, rect, null);
                    if(timerCount > 0 && starSlot == 1) {
                        int size = width * 30 / 50;
                        int difference = (width - size) / 2;
                        Rect starRect = new Rect(x + (timerCount - 1) * (10 + width) + difference, y1 + difference, (x + width) * (timerCount) - difference, y1 + width - difference);
                        canvas.drawBitmap(star, null, starRect, null);
                    }
                }
            }
            if(i >= 4) {
                Rect rect = new Rect(x + (i % 4) * (10 + width), y2, (x + width) * ((i % 4) + 1), y2 + width);
                if(endGameCount == Math.ceil(limit) && endSlot == 2) {
                    if((i%4)==p2) {
                        endRadiusCount += 1;
                        if (endRadiusCount > 23) {
                            star.recycle();
                            loopCount = loopCount%starInterval;
                            Cryptography.saveFile((loopCount + "").getBytes(), context, "interval");
                            endGameCount = 0;
                            exception = true;
                            throw new GameOverException(color);
                        }

                        rect = new Rect(x + (i % 4) * (10 + width) - endRadiusCount*(int)Math.ceil(endRadiusSpeed), y2 - endRadiusCount*(int)Math.ceil(endRadiusSpeed), (x + width) * ((i % 4) + 1) + endRadiusCount*(int)Math.ceil(endRadiusSpeed), y2 + width + endRadiusCount*(int)Math.ceil(endRadiusSpeed));
                        canvas.drawBitmap(bitmaps.get(i), null, rect, null);
                    }
                }
                else if((i%4)==p2 && touchedSecond) {
                    rect = new Rect(x + (i % 4) * (10 + width) + 3*count2 + ((int)speedY1-15), y2 + 3*count2 + ((int)speedY1-15), (x + width) * ((i % 4) + 1) - 3*count2 - ((int)speedY1-15), y2 + width - 3*count2 - ((int)speedY1-15));
                    canvas.drawBitmap(bitmaps.get(i), null, rect, null);
                    count2++;
                }
                else if(endSlot != 1) {
                    canvas.drawBitmap(bitmaps.get(i), null, rect, null);
                    if(timerCount > 0 && starSlot == 2) {
                        int size = width * 30 / 50;
                        int difference = (width - size) / 2;
                        Rect starRect = new Rect(x + (timerCount - 1) * (10 + width) + difference, y2 + difference, (x + width) * (timerCount) - difference, y2 + width - difference);
                        canvas.drawBitmap(star, null, starRect, null);
                    }
                }
            }
        }
        Rect src = new Rect(circles.get(color).getWidth()/2 - 10,circles.get(color).getHeight()/2 - 10,circles.get(color).getWidth()/2 + 10,circles.get(color).getHeight()/2 + 10);
        Rect dst;

        Paint paint = new Paint();
        paint.setColor(Color.WHITE);
        paint.setTextAlign(Paint.Align.RIGHT);
        paint.setTypeface(Typeface.SANS_SERIF);
        paint.setTextSize(72 * ratio);
        canvas.drawText(GameView.score + " ", GameActivity.SCREEN_WIDTH, width / 2, paint);

        dst = new Rect(5,5, (int) (120 * ratio - 5), (int) (120 * ratio - 5));
        canvas.drawBitmap(star,null,dst,null);
        paint.setTextAlign(Paint.Align.LEFT);
        canvas.drawText("" + GameView.stars, 120 * ratio, width/2, paint);
    }
}

2 个答案:

答案 0 :(得分:1)

不要覆盖draw()。这用于渲染视图而不是Surface,即使您正在创建自定义视图,也通常不应该覆盖该方法:

  

实现视图时,实现onDraw(android.graphics.Canvas)而不是覆盖此方法。

SurfaceViews有两个部分,Surface和View。 View部分的处理方式与任何其他View一样,但通常只是布局中的透明“洞”。 Surface是一个单独的图层,默认情况下位于View图层后面。无论你在Surface上绘制什么,都会“穿透”透明孔。

通过覆盖draw(),只要View UI无效,您就会在视图上绘图。你也是从渲染线程调用draw(),所以你在Surface上绘图,但是由于View内容是完全不透明的,因此你无法看到它。通过不在两个不同的层中绘制所有内容,您将减少对UI线程的影响。

除非您刻意使用View,否则最好完全避免对SurfaceView进行子类化,并将其用作成员。

因为您的绘图代码是同步的,所以两个绘图过程不会同时执行。这意味着您的View图层绘制调用将阻止等待Surface图层渲染完成。 Surface上的Canvas渲染不是硬件加速的,因此如果您触摸大量像素,它可能会变慢,并且UI线程将不得不等待它运行。这不会那么糟糕,但是当你正在睡觉时,你仍然坚持使用互斥锁,这意味着主要UI线程运行的唯一机会是在循环回绕的短暂瞬间。线程调度程序不保证公平性,因此完全有可能以这种方式使主UI线程饿死。

如果您将@override draw()更改为myDraw(),事情会变得更好。您应该根据一般原则将睡眠呼叫从同步块中移出,或者工作到eliminate it entirely。您可能还需要考虑使用custom View而不是SurfaceView。

在不相关的说明中,您应该避免每次更新都这样做:

Random random = new Random();

出于注明here的原因。

答案 1 :(得分:1)

成功解决了这个问题。无法想象,与我考虑复杂性的问题相比,解决方案会非常简单。只是将帧速率从120降低到90并猜测是什么,它就像魅力一样!

由于帧速率很高,SurfaceView忙于完成所有绘图,onTouchEvent()方法不得不饿死