我一直在获取java.lang.IllegalArgumentException:表面已被锁定

时间:2018-07-02 01:38:08

标签: java android

启动游戏视图时,我不断收到相同的错误消息。问题似乎与stacktrace所说的游戏线程有关,但我不太确定。当我不启动游戏视图中的第二个线程时,问题似乎消失了。

W/System.err: java.lang.IllegalArgumentException: millis < 0: -84
W/System.err:     at java.lang.Thread.sleep(Thread.java:346)
                  at java.lang.Thread.sleep(Thread.java:314)
                  at com.zeropointengine.popper.GameThread.run(GameThread.java:69)
E/SurfaceHolder: Exception locking surface
                 java.lang.IllegalArgumentException: Surface was already locked
                     at android.view.Surface.lockCanvas(Surface.java:328)
                     at android.view.SurfaceView$3.internalLockCanvas(SurfaceView.java:1120)
                     at android.view.SurfaceView$3.lockCanvas(SurfaceView.java:1080)
                     at com.zeropointengine.popper.GameThread.run(GameThread.java:44)

这是代码本身。下面的类是游戏循环

package com.zeropointengine.popper;

import android.graphics.Canvas;
import android.view.SurfaceHolder;


/**
 * Created by GhostFreak on 2018-05-05.
 */

public class GameThread extends Thread {
    private GameView gv;
    private SurfaceHolder surfaceHolder;
    private boolean running;
    private static Canvas canvas;
    private int targetFPS = 30;

    public boolean isRunning() {
        return running;
    }

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

    public GameThread(SurfaceHolder surfaceHolder, GameView gv){
        this.surfaceHolder = surfaceHolder;
        this.gv = gv;
    }


    @Override
    public void run(){

        long startTime;
        long time;
        long fps;

        while(running){
            startTime = System.nanoTime();
            canvas = null;

            try{
                canvas = this.surfaceHolder.lockCanvas();
                synchronized (surfaceHolder){
                    if(canvas != null){
                        this.gv.update();
                        this.gv.draw(canvas);
                    }
                }

            }catch(Exception e){
                e.printStackTrace();
            }finally {
                if(canvas != null){
                    try{
                        surfaceHolder.unlockCanvasAndPost(canvas);
                    }catch(Exception e){
                        e.printStackTrace();
                    }

                }
            }

            time = (System.nanoTime() - startTime)/ 1000000;
            fps = targetFPS - time;

            try{
                this.sleep(fps);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
}

游戏视图

package com.zeropointengine.popper;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

/**
 * Created by GhostFreak on 2018-05-05.
 */

public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable, View.OnTouchListener {
    GameActivity gActivity;
    GameThread thread;
    Thread spawn;

    Bitmap scaled;
    Random random;
    Rect screen;

    int height;
    int width;
    int ranX;
    int score = 0;
    boolean running;

    List<Bubble> bubbles = new ArrayList<>();
    Context context;

    public GameView(Activity activity, Context context) {
        super(activity);
        gActivity = (GameActivity) activity;

        this.setZOrderOnTop(true);
        this.getHolder().addCallback(this);

        this.context = context;

        setOnTouchListener(this);

        thread = new GameThread(this.getHolder(), this);
        spawn = new Thread(this);

        screen = new Rect(0, 0, width, height);

        setFocusable(true);

    }

    public GameView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public GameView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight) {
        int width = bm.getWidth();
        int height = bm.getHeight();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // CREATE A MATRIX FOR THE MANIPULATION
        Matrix matrix = new Matrix();
        // RESIZE THE BIT MAP
        matrix.postScale(scaleWidth, scaleHeight);

        // "RECREATE" THE NEW BITMAP
        Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
        bm.recycle();
        return resizedBitmap;
    }

    @Override
    public void onDraw(Canvas canvas){
        super.onDraw(canvas);

        Typeface font = Typeface.createFromAsset(context.getAssets(), "fonts/Delicious.ttf");
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.WHITE);

        if(canvas != null){
            canvas.drawRGB(8, 8, 8);
            paint.setTypeface(font);
            paint.setTextSize(112);
            paint.setTextAlign(Paint.Align.CENTER);

            canvas.drawText("Score: " + score, width/2, 90, paint);

           drawBubble(canvas, paint);

        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        thread.setRunning(true);
        running = true;
        thread.start();
        spawn.start();

        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        width = size.x;
        height = size.y;


    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
       restart();
    }

    public void update(){
        updateBubble();

    }

    @Override
    public void run() {
        random = new Random();
        try{
            Thread.sleep(1000);
            while(running){
                ranX = random.nextInt((width-200));
                addBubble(new Bubble(getResizedBitmap(BitmapFactory.decodeResource(getResources(),R.drawable.bubble_white), 200, 200) , ranX, height, this));
                Thread.sleep(3000);
            }

        }catch(Exception e){
            System.out.println("You got an error mate:\n"+ e.getMessage());
            e.printStackTrace();
        }

    }

    public void addBubble(Bubble bubble){
        bubbles.add(bubble);
    }

    public void removeBubble(Bubble bubble){
        Iterator <Bubble> it = bubbles.iterator();
        while(it.hasNext()){
            Bubble bub = it.next();
            //your stuff
            it.remove();
        }
    }

    public void drawBubble(Canvas canvas, Paint paint){
        for(Bubble bubble: bubbles){
            bubble.draw(canvas, paint);
        }
    }

    public void updateBubble(){
        for(Bubble bubble : bubbles){
            bubble.update();
        }
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        for(Bubble bubble: bubbles){
           if(bubble.bounds.intersect((int) motionEvent.getX()-50, (int) motionEvent.getY()-50,(int) motionEvent.getX()-50 , (int) motionEvent.getY()-50)){
               if(bubble.poppable){
                   bubble.popped();
               }
           }
        }
        if(screen.intersect((int) motionEvent.getX(), (int) motionEvent.getY(), (int) motionEvent.getX(), (int) motionEvent.getY())){
            System.out.println("Screen clicked");
        }

        return true;
    }

    public void restart(){
        score = 0;
        boolean retry = true;
        thread.setRunning(false);
        running = false;
        while(retry){
            try{
                thread.join();
                spawn.join();
                retry = false;
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
}

任何其他建议,我们将不胜感激。我仍然是android的初学者。

0 个答案:

没有答案