当我尝试在Canvas上绘图时,我得到一个NullPointerException。我不确定问题出在哪里或从何处开始。这是一个问题,我有两个不同的对象同时绘制?请帮忙。谢谢。
public class RainbowWallpaper extends AnimationWallpaper {
@Override
public Engine onCreateEngine() {
return new RainbowEngine();
}
class RainbowEngine extends AnimationEngine {
// -------------------------------------------------
private GlowDrawable mDrawable;
private boolean mVisible = false;
private final Handler mHandler = new Handler();
private final Runnable mUpdateDisplay = new Runnable() {
public void run() {
draw();
}
};
// -------------------------------------------------
public RainbowEngine() {
mDrawable = new GlowDrawable();
}
int offsetX;
int offsetY;
int height;
int width;
int visibleWidth;
Set<RainbowCircle> circles = new HashSet<RainbowCircle>();
int iterationCount = 0;
Paint paint = new Paint();
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
// By default we don't get touch events, so enable them.
setTouchEventsEnabled(true);
}
//------------------------------------------------------------
private void draw() {
SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
mDrawable.setBounds(c.getClipBounds());
mDrawable.draw(c);
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
mHandler.removeCallbacks(mUpdateDisplay);
if (mVisible) {
mHandler.postDelayed(mUpdateDisplay, 100);
}
}
//------------------------------------------------------------
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
//-------------------------------------------------------
draw();
//-------------------------------------------------------
this.height = height;
if (this.isPreview()) {
this.width = width;
} else {
this.width = 2 * width;
}
this.visibleWidth = width;
for (int i = 0; i < 20; i++) {
this.createRandomCircle();
}
super.onSurfaceChanged(holder, format, width, height);
}
@Override
public void onOffsetsChanged(float xOffset, float yOffset,
float xOffsetStep, float yOffsetStep, int xPixelOffset,
int yPixelOffset) {
// store the offsets
this.offsetX = xPixelOffset;
this.offsetY = yPixelOffset;
super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep,
xPixelOffset, yPixelOffset);
}
@Override
public Bundle onCommand(String action, int x, int y, int z,
Bundle extras, boolean resultRequested) {
if ("android.wallpaper.tap".equals(action)) {
createCircle(x - this.offsetX, y - this.offsetY);
}
return super.onCommand(action, x, y, z, extras, resultRequested);
}
@Override
protected void drawFrame() {
SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
draw(c);
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
}
void draw(Canvas c) {
c.save();
c.drawColor(0xff000000);
draw();
synchronized (circles) {
for (RainbowCircle circle : circles) {
if (circle.alpha == 0)
continue;
// intersects with the screen?
float minX = circle.x - circle.radius;
if (minX > (-this.offsetX + this.visibleWidth)) {
continue;
}
float maxX = circle.x + circle.radius;
if (maxX < -this.offsetX) {
continue;
}
paint.setAntiAlias(true);
// paint the fill
paint.setColor(Color.argb(circle.alpha,
Color.red(circle.color), Color.green(circle.color),
Color.blue(circle.color)));
paint.setStyle(Paint.Style.FILL_AND_STROKE);
c.drawCircle(circle.x + this.offsetX, circle.y
+ this.offsetY, circle.radius, paint);
// paint the contour
paint.setColor(Color.argb(circle.alpha,
63 + 3 * Color.red(circle.color) / 4,
63 + 3 * Color.green(circle.color) / 4,
63 + 3 * Color.blue(circle.color) / 4));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3.0f);
c.drawCircle(circle.x + this.offsetX, circle.y
+ this.offsetY, circle.radius, paint);
}
}
c.restore();
}
@Override
protected void iteration() {
synchronized (circles) {
for (Iterator<RainbowCircle> it = circles.iterator(); it
.hasNext();) {
RainbowCircle circle = it.next();
circle.tick();
if (circle.isDone())
it.remove();
}
iterationCount++;
if (isPreview() || iterationCount % 2 == 0)
createRandomCircle();
}
super.iteration();
}
void createRandomCircle() {
int x = (int) (width * Math.random());
int y = (int) (height * Math.random());
createCircle(x, y);
}
int getColor(float yFraction) {
return Color.HSVToColor(new float[] { 360.0f * yFraction, 1.0f,
1.0f });
}
void createCircle(int x, int y) {
float radius = (float) (40 + 20 * Math.random());
float yFraction = (float) y / (float) height;
yFraction = yFraction + 0.05f - (float) (0.1f * (Math.random()));
if (yFraction < 0.0f)
yFraction += 1.0f;
if (yFraction > 1.0f)
yFraction -= 1.0f;
int color = getColor(yFraction);
int steps = 40 + (int) (20 * Math.random());
RainbowCircle circle = new RainbowCircle(x, y, radius, color, steps);
synchronized (this.circles) {
this.circles.add(circle);
}
}
}
public class GlowDrawable extends ShapeDrawable {
private Rect mBounds;
private float mCenterX = 0.0f;
private float mCenterY = 0.0f;
private float mOffsetX = 40.0f;
private float mOffsetY = 80.0f;
private float mRadius = 0.0f;
private float mSpeedX = 10.0f;
private float mSpeedY = 20.0f;
private int mColorFG = Color.rgb(0xFF, 0xFF, 0x00); // yellow
private int mColorBG = Color.rgb(0xFF, 0x66, 0x33); // orange
public GlowDrawable() {
this(new RectShape());
}
public GlowDrawable(Shape s) {
super(s);
}
public void setBounds(Rect bounds) {
super.setBounds(bounds);
mBounds = bounds;
if (mRadius == 0.0f) {
mCenterX = (mBounds.right - mBounds.left) / 2.0f;
mCenterY = (mBounds.bottom - mBounds.top) / 2.0f;
mRadius = mCenterX + mCenterY;
}
}
public void animate() {
mCenterX += mSpeedX;
mCenterY += mSpeedY;
if (mCenterX < mBounds.left + mOffsetX
|| mCenterX > mBounds.right - mOffsetX) {
mSpeedX *= -1.0f;
}
if (mCenterY < mBounds.top + mOffsetY
|| mCenterY > mBounds.bottom - mOffsetY) {
mSpeedY *= -1.0f;
}
}
public Paint getPaint(float width, float height) {
animate();
RadialGradient shader = new RadialGradient(mCenterX, mCenterY,
mRadius, mColorFG, mColorBG, Shader.TileMode.CLAMP);
Paint paint = new Paint();
paint.setShader(shader);
return paint;
}
public void draw(Canvas c) {
float width = c.getWidth();
float height = c.getHeight();
c.drawRect(0, 0, width, height, getPaint(width, height));
}
}
Logcat错误:
03-07 04:44:39.242: E/AndroidRuntime(28591): FATAL EXCEPTION: main
03-07 04:44:39.242: E/AndroidRuntime(28591): java.lang.NullPointerException
03-07 04:44:39.242: E/AndroidRuntime(28591): at com.gordon.rainbowcircles.RainbowWallpaper$RainbowEngine.draw(RainbowWallpaper.java:65)
03-07 04:44:39.242: E/AndroidRuntime(28591): at com.gordon.rainbowcircles.RainbowWallpaper$RainbowEngine.onSurfaceChanged(RainbowWallpaper.java:83)
03-07 04:44:39.242: E/AndroidRuntime(28591): at android.service.wallpaper.WallpaperService$Engine.updateSurface(WallpaperService.java:693)
03-07 04:44:39.242: E/AndroidRuntime(28591): at android.service.wallpaper.WallpaperService$Engine.attach(WallpaperService.java:781)
03-07 04:44:39.242: E/AndroidRuntime(28591): at android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper.executeMessage(WallpaperService.java:1031)
03-07 04:44:39.242: E/AndroidRuntime(28591): at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:40)
03-07 04:44:39.242: E/AndroidRuntime(28591): at android.os.Handler.dispatchMessage(Handler.java:99)
03-07 04:44:39.242: E/AndroidRuntime(28591): at android.os.Looper.loop(Looper.java:213)
03-07 04:44:39.242: E/AndroidRuntime(28591): at android.app.ActivityThread.main(ActivityThread.java:5225)
03-07 04:44:39.242: E/AndroidRuntime(28591): at java.lang.reflect.Method.invokeNative(Native Method)
03-07 04:44:39.242: E/AndroidRuntime(28591): at java.lang.reflect.Method.invoke(Method.java:525)
03-07 04:44:39.242: E/AndroidRuntime(28591): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
03-07 04:44:39.242: E/AndroidRuntime(28591): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
03-07 04:44:39.242: E/AndroidRuntime(28591): at dalvik.system.NativeStart.main(Native Method)
我在我的引擎的构造函数中创建了一个新的GlowDrawable现在我收到了这个错误。我只能锁定SurfaceView一次......?
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): Exception locking surface
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): java.lang.RuntimeException: Surface was already locked
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at android.view.Surface.lockCanvas(Surface.java:242)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at com.android.internal.view.BaseSurfaceHolder.internalLockCanvas(BaseSurfaceHolder.java:184)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at com.android.internal.view.BaseSurfaceHolder.lockCanvas(BaseSurfaceHolder.java:157)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at com.gordon.rainbowcircles.RainbowWallpaper$RainbowEngine.draw(RainbowWallpaper.java:68)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at com.gordon.rainbowcircles.RainbowWallpaper$RainbowEngine.draw(RainbowWallpaper.java:147)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at com.gordon.rainbowcircles.RainbowWallpaper$RainbowEngine.drawFrame(RainbowWallpaper.java:135)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at com.gordon.rainbowcircles.AnimationWallpaper$AnimationEngine.onSurfaceChanged(AnimationWallpaper.java:44)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at com.gordon.rainbowcircles.RainbowWallpaper$RainbowEngine.onSurfaceChanged(RainbowWallpaper.java:101)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at android.service.wallpaper.WallpaperService$Engine.updateSurface(WallpaperService.java:693)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at android.service.wallpaper.WallpaperService$Engine.attach(WallpaperService.java:781)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper.executeMessage(WallpaperService.java:1031)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:40)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at android.os.Handler.dispatchMessage(Handler.java:99)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at android.os.Looper.loop(Looper.java:213)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at android.app.ActivityThread.main(ActivityThread.java:5225)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at java.lang.reflect.Method.invokeNative(Native Method)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at java.lang.reflect.Method.invoke(Method.java:525)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
03-07 05:19:15.389: E/BaseSurfaceHolder(4046): at dalvik.system.NativeStart.main(Native Method)
03-07 05:19:15.489: D/AndroidRuntime(4046): Shutting down VM
03-07 05:19:15.489: W/dalvikvm(4046): threadid=1: thread exiting with uncaught exception (group=0x4203e8b0)
03-07 05:19:15.489: E/AndroidRuntime(4046): FATAL EXCEPTION: main
03-07 05:19:15.489: E/AndroidRuntime(4046): java.lang.NullPointerException
03-07 05:19:15.489: E/AndroidRuntime(4046): at com.gordon.rainbowcircles.RainbowWallpaper$RainbowEngine.draw(RainbowWallpaper.java:69)
03-07 05:19:15.489: E/AndroidRuntime(4046): at com.gordon.rainbowcircles.RainbowWallpaper$RainbowEngine.draw(RainbowWallpaper.java:147)
03-07 05:19:15.489: E/AndroidRuntime(4046): at com.gordon.rainbowcircles.RainbowWallpaper$RainbowEngine.drawFrame(RainbowWallpaper.java:135)
03-07 05:19:15.489: E/AndroidRuntime(4046): at com.gordon.rainbowcircles.AnimationWallpaper$AnimationEngine.onSurfaceChanged(AnimationWallpaper.java:44)
03-07 05:19:15.489: E/AndroidRuntime(4046): at com.gordon.rainbowcircles.RainbowWallpaper$RainbowEngine.onSurfaceChanged(RainbowWallpaper.java:101)
03-07 05:19:15.489: E/AndroidRuntime(4046): at android.service.wallpaper.WallpaperService$Engine.updateSurface(WallpaperService.java:693)
03-07 05:19:15.489: E/AndroidRuntime(4046): at android.service.wallpaper.WallpaperService$Engine.attach(WallpaperService.java:781)
03-07 05:19:15.489: E/AndroidRuntime(4046): at android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper.executeMessage(WallpaperService.java:1031)
03-07 05:19:15.489: E/AndroidRuntime(4046): at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:40)
03-07 05:19:15.489: E/AndroidRuntime(4046): at android.os.Handler.dispatchMessage(Handler.java:99)
03-07 05:19:15.489: E/AndroidRuntime(4046): at android.os.Looper.loop(Looper.java:213)
03-07 05:19:15.489: E/AndroidRuntime(4046): at android.app.ActivityThread.main(ActivityThread.java:5225)
03-07 05:19:15.489: E/AndroidRuntime(4046): at java.lang.reflect.Method.invokeNative(Native Method)
03-07 05:19:15.489: E/AndroidRuntime(4046): at java.lang.reflect.Method.invoke(Method.java:525)
03-07 05:19:15.489: E/AndroidRuntime(4046): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
03-07 05:19:15.489: E/AndroidRuntime(4046): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
03-07 05:19:15.489: E/AndroidRuntime(4046): at dalvik.system.NativeStart.main(Native Method)