I'm working on a game app. I'm coding using Android Studio and I decided to go through a tutorial to help me understand MotionEvents, Threads, etc. When I finished the tutorial the idea of the code is to allow me to pressure anywhere on the top of the screen and the LogCat is suppose to give me the x and y coordinates, and if I click anywhere on the bottom of the screen the application should stop. Now, the problem is that the game unexpectedly stop working as soon as you click on the app, and I believe the problem is because the tutorial was made in 2010, and the newer android versions are conflicting with it somehow, but I'm having trouble knowing where to start. I'll show the code and any errors that come up when trying to run the app:
package com.example.dsdude.gameexample;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MainGamePanel extends SurfaceView implements SurfaceHolder.Callback {
private MainThread thread;
private static final String TAG = MainGamePanel.class.getSimpleName();
public MainGamePanel(Context context) {
super(context);
//adding the callback (this) to the surface holder to intercept events
getHolder().addCallback(this);
//create the game loop thread
thread = new MainThread(getHolder(), this);
//make the GamePanel focusable so it can handle events
setFocusable(true);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
thread.setRunning(true);
thread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(TAG, "Surface is being destroyed");
boolean retry = true;
while (retry) {
try {
thread.setRunning(false);
thread.join();
((Activity)getContext()).finish();
} catch (InterruptedException e) {
e.printStackTrace();
// try again shutting down the thread
}
retry = false;
}
Log.d(TAG, "Thread was shut down cleanly");
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (event.getY() > getHeight() - 50) {
thread.setRunning(false);
((Activity)getContext()).finish();
} else {
Log.d(TAG, "Coords: x=" + event.getX() + ",y=" + event.getY());
}
}
return super.onTouchEvent(event);
}
@Override
protected void onDraw(Canvas canvas) {
}
}
package com.example.dsdude.gameexample;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
public class DroidzActivity extends Activity {
/**
* Called when the activity is first created.
*/
private static final String TAG = DroidzActivity.class.getSimpleName();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// requesting to turn the title OFF
requestWindowFeature(Window.FEATURE_NO_TITLE);
// making it full screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
// set our MainGamePanel as the View
setContentView(new MainGamePanel(this));
Log.d(TAG, "View added");
}
@Override
protected void onDestroy() {
Log.d(TAG, "Destroying...");
super.onDestroy();
}
@Override
protected void onStop() {
Log.d(TAG, "Stopping...");
super.onStop();
}
}
package com.example.dsdude.gameexample;
import android.util.Log;
import android.view.SurfaceHolder;
public class MainThread extends Thread {
private static final String TAG = MainThread.class.getSimpleName();
private SurfaceHolder surfaceHolder;
private MainGamePanel gamePanel;
//flag to hold game state
private boolean running;
public void setRunning(boolean running) {
this.running = running;
}
@Override
public void run() {
long tickCount = 0L;
Log.d(TAG, "Starting game loop");
while (running) {
tickCount++;
//update game state
//render state to the screen
}
Log.d(TAG, "Game loop executed " + tickCount + " times");
}
public MainThread(SurfaceHolder surfaceHolder, MainGamePanel gamePanel) {
super();
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
}
}
Here is the logcat:
02-18 16:08:01.091 1065-1065/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.dsdude.gameexample, PID: 1065
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.dsdude.gameexample/com.example.dsdude.gameexample.MainGamePanel}: java.lang.InstantiationException: class com.example.dsdude.gameexample.MainGamePanel has no zero argument constructor
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2999)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3263)
at android.app.ActivityThread.access$1000(ActivityThread.java:197)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1687)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6897)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
Caused by: java.lang.InstantiationException: class com.example.dsdude.gameexample.MainGamePanel has no zero argument constructor
at java.lang.Class.newInstance(Class.java:1681)
at android.app.Instrumentation.newActivity(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2989)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3263)
at android.app.ActivityThread.access$1000(ActivityThread.java:197)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1687)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6897)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
Caused by: java.lang.NoSuchMethodException: <init> []
at java.lang.Class.getConstructor(Class.java:531)
at java.lang.Class.getDeclaredConstructor(Class.java:510)
at java.lang.Class.newInstance(Class.java:1679)
at android.app.Instrumentation.newActivity(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2989)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3263)
at android.app.ActivityThread.access$1000(ActivityThread.java:197)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1687)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6897)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
02-18 16:11:34.411 1065-1065/com.example.dsdude.gameexample I/Process: Sending signal. PID: 1065 SIG: 9
Any help would be appreciated, I just want to know what direction I should be going with this to understand what the problem could be. The program compiles just fine, there are no errors, but something has to be wrong with the MainGamePanel.java for it not to be able to instantiate an activity.