Reputation: 13
So I keep running into a NullPointerException with a project I am doing in Android Studio. I need to get an image to show up in a custom class I'm calling DrawSurface. I just can't seem to find anything that relates to my issue. I've checked various previous questions and watched so many videos.
The error I'm thrown looks like this:
java.lang.NullPointerException at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1269) at android.graphics.Canvas.drawBitmap(Canvas.java:1325) at edu.########.#####.cse.treasurehunter.###########.DrawSurface.onDraw_Original(DrawSurface.java:60) at edu.########.#####.cse.treasurehunter.###########.DrawSurface.onDraw(DrawSurface.java:-1)
My .xml looks like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="fill_parent" android:orientation="vertical" tools:context=".MainActivity">
<edu.########.####.cse.treasurehunter.###########.DrawSurface android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" android:id="@+id/dsField"/>
<LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="50dp">
<Button android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.5" android:text="View Inventory" android:id="@+id/btnInventory"/>
<Button android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="0.5" android:text="Credits" android:id="@+id/btnCredits"/>
</LinearLayout>
And my DrawSurface class looks like this:
public class DrawSurface extends SurfaceView {
private Bitmap mBMPField;
private SurfaceHolder holder;
public DrawSurface(Context context) {
super(context);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Canvas c = holder.lockCanvas();
onDraw(c);
holder.unlockCanvasAndPost(c);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
mBMPField = BitmapFactory.decodeResource(getResources(), R.drawable.field);
}
public DrawSurface(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DrawSurface(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.DKGRAY);
canvas.drawBitmap(mBMPField, 100, 200, null);
}
}
Upvotes: 1
Views: 781
Reputation: 13
Ok so what happened was I didn't have an initialization function stated within my constructor. So once I started using Init(); I got it working. Thank you again for the pointers and direction. Without it I wouldn't have noticed this part.
Upvotes: 0
Reputation: 52303
onDraw()
if your goal is to draw on the SurfaceView's Surface (as opposed to the SurfaceView's View). onDraw()
is for custom views. If you really want to use a Surface, name the method something else.surfaceChanged()
unless you're posting a static image. That method will usually be called once, when the Surface is first created, unless something changes the Surface's size. If you just want a static image from a Bitmap, consider using an ImageView instead.lockCanvas()
will succeed. You're pretty safe calling it from surfaceChanged()
, but in general you'll want to check the return value.BitmapFactory.decodeResource()
will succeed.Since your drawColor()
call is succeeding, and your drawBitmap()
call is failing, my guess is that mBMPField
is null. According to the docs for decodeResource()
:
[Returns] The decoded bitmap, or null if the image data could not be decoded, ...
It's returning null on error, not throwing an exception, so you'll need to check the return value.
Upvotes: 1