I am a little new to android app development, so forgive my rookie code. I am trying to program a game based on movement. As you rotate your phone, it slides an object (a bucket) right to left on the screen to catch falling objects. I have a Main Activity and a private SurfaceView within this class. I also have a custom thread in which this runs.
This is the error: FATAL EXCEPTION: main Process: course.examples.databaseanimation, PID: 17583 java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference at android.graphics.Bitmap.createBitmap(Bitmap.java:659) at course.examples.databaseanimation.BucketThread.(BucketThread.java:25) at course.examples.databaseanimation.MainActivity$BucketView.surfaceCreated(MainActivity.java:102) at android.view.SurfaceView.updateWindow(SurfaceView.java:582) at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:177) at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2067) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1119) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6060) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858) at android.view.Choreographer.doCallbacks(Choreographer.java:670) at android.view.Choreographer.doFrame(Choreographer.java:606) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844) at android.os.Handler.handleCallback(Handler.java:746) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5443) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
This is my Thread:
public class BucketThread extends Thread {
private SurfaceHolder holder;
private boolean running = true;
private float shiftY;
private float vy;
private float x;
private Bitmap mBucket = Bitmap.createBitmap(BitmapFactory.decodeResource
(Resources.getSystem(), R.mipmap.ic_launcher));
public BucketThread(SurfaceHolder holder){
this.holder = holder;
x = 0;
}
public void run(){
while(running){
Canvas canvas = null;
try{
canvas = holder.lockCanvas();
synchronized (holder){
//update
vy += shiftY * 0.1;
x += vy;
//draw
Paint mPaint = new Paint();
canvas.drawBitmap(mBucket, x, 0, mPaint);
}
}
finally {
if(canvas != null){
holder.unlockCanvasAndPost(canvas);
}
}
}
}
public void setRunning(boolean r){
running = r;
}
public void setShift(float shiftY){
this.shiftY = shiftY;
}
}
And this is my Main Activity:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout mainFrame = (RelativeLayout) findViewById
(R.id.main_frame);
BucketView bv = new BucketView(getApplicationContext());
mainFrame.addView(bv);
}
private class BucketView extends SurfaceView implements SurfaceHolder.Callback,
SensorEventListener {
//private final Bitmap mBucket;
//private DisplayMetrics mDisplay;
private SurfaceHolder mSurfaceHolder;
private BucketThread mBuckThread;
//private int mDisplayWidth;
//private float mY;
public BucketView(Context context) {
super(context);
mSurfaceHolder = getHolder();
mSurfaceHolder.addCallback(this);
SensorManager manager = (SensorManager) context.getSystemService
(Context.SENSOR_SERVICE);
if (manager.getSensorList(Sensor.TYPE_ACCELEROMETER).size() != 0) {
Sensor accelerometer = manager.getSensorList(Sensor
.TYPE_ACCELEROMETER).get(0);
manager.registerListener(this, accelerometer, SensorManager
.SENSOR_DELAY_GAME);
}
}
@Override
public void onSensorChanged(SensorEvent event) {
if (mBuckThread != null) {
mBuckThread.setShift(event.values[1]);
Log.i("Main Activity", getClass().getSimpleName() + "onSensorChanged");
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mBuckThread = new BucketThread(holder);
mBuckThread.setRunning(true);
mBuckThread.start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
mBuckThread.setRunning(false);
while (retry) {
try {
mBuckThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
}
}