Android应用程序死于表面更改

时间:2014-12-09 17:44:09

标签: android surfaceview

我是Android编程新手。我试图围绕基本图形和输入编写一些非常简单的应用程序。我正在使用的应用程序现在使用SurfaceView并使用Canvas绘制到它。它只是在屏幕中间画一个圆圈,每秒都会改变颜色。这是我的SurfaceView:

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {

public class DrawerThread extends Thread {

    private SurfaceHolder mSurfaceHolder;

    private long mTimeStep;
    private long mTime;
    private long mPhysicsTime;

    private boolean mRun;

    private int mCanvasWidth;
    private int mCanvasHeight;

    private int colorIter;

    private int colors[][] = {
            {255, 255, 0, 0},
            {255, 0, 255, 0}
    };

    Paint mPaint;

    public DrawerThread(SurfaceHolder surfaceHolder) {
        mSurfaceHolder = surfaceHolder;
        mTimeStep = 1000;
        mRun = false;
        mCanvasWidth = 1;
        mCanvasHeight = 1;
        colorIter = 0;
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
    }

    public void setRunning(boolean value) {
        if(value == true && mRun != true) {
            mTime = System.currentTimeMillis();
            mPhysicsTime = 0;
        }
        mRun = value;
    }

    public void setSurfaceSize(int width, int height) {
        synchronized (mSurfaceHolder) {
            mCanvasWidth = width;
            mCanvasHeight = height;
        }
    }

    private void doPhysics(long time) {
        long deltaTime = time - mTime;
        mPhysicsTime += deltaTime;
        mTime = time;
        int steps = (int) (mPhysicsTime / mTimeStep);
        mPhysicsTime -= steps * mTimeStep;
        colorIter = (colorIter + steps) % colors.length;
    }

    private void doDraw(Canvas canvas) {
        canvas.drawColor(Color.argb(255, 0, 0, 0));
        mPaint.setARGB(colors[colorIter][0], colors[colorIter][1], colors[colorIter][2], colors[colorIter][3]);
        canvas.drawCircle(mCanvasWidth/2, mCanvasHeight/2, 100, mPaint);
    }

    @Override
    public void run() {
        while(mRun) {
            Canvas canvas = null;
            try {
                synchronized (mSurfaceHolder) {
                    canvas = mSurfaceHolder.lockCanvas();
                    doPhysics(System.currentTimeMillis());
                    doDraw(canvas);
                }
            } finally {
                if(canvas != null) {
                    mSurfaceHolder.unlockCanvasAndPost(canvas);
                }
            }
        }
    }
}

private DrawerThread mDrawerThread;

public MySurfaceView(Context context) {
    super(context);
    SurfaceHolder surfaceHolder = getHolder();
    surfaceHolder.addCallback(this);
    mDrawerThread = new DrawerThread(surfaceHolder);
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    mDrawerThread.setRunning(true);
    mDrawerThread.start();
}

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

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    boolean retry = true;
    mDrawerThread.setRunning(false);
    while(retry) {
        try{
            mDrawerThread.join();
            retry = false;
        } catch(InterruptedException e) {}
    }
}
}

我根据此处提供的Lunar Landing示例编写了此代码: https://gitorious.org/replicant/development/source/3eda8fc3859c243df4a1f892a11e2da84b49cb94:samples/LunarLander/src/com/example/android/lunarlander/LunarView.java#L8

我试图让它更简单,所以我省略了我能做到的事情。所以应用程序正在工作,直到我从配置文件视图更改为横向或使用“最近”按钮。这两个操作都会在函数doDraw()中的canvas.drawColor(...)行中使我的应用程序崩溃,nullpointer异常。我怎么能这个问题?

第二个问题:我尝试通过在绘图线程中的run()中放置一个Thread.sleep(<>)来限制我的绘图线程。但是,我注意到当这个线程处于休眠状态时,当我将手机侧向翻转时(从配置文件到横向),屏幕不会翻转。为什么睡眠的拉丝线会阻挡表面变化?

第三个问题:为什么我需要在surfaceDestroyed()中使用while循环? mDrawerThread.join()不是阻塞函数吗?

我知道基本的Java,但我对android编程几乎没有任何知识,所以我要感谢任何建设性的评论。 (IDE:Android Studio)

0 个答案:

没有答案