我是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)