SurfaceView Draw方法的Android NullPointer异常

时间:2014-03-07 09:48:44

标签: android nullpointerexception surfaceview live-wallpaper

当我尝试在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)

0 个答案:

没有答案