Ich habe eine Runnable GameView
, die einige Animationen zeichnen, und es wird erstellt und in NewGame
Aktivität verwendet. Und NewGame
startet eine andere Aktivität mit dem Namen PetInfo
onClick einer Schaltfläche in der Ansicht. Aber wenn ich PetInfo
starte, erhalte ich folgende Fehler:Android: Starten Sie eine Aktivität aus einer ausführbaren Aktivität (NullPointerException)
04-06 19: 13: 30.025 23272-23272 /? I/art: Spätes ermöglich -Xcheck: jni
04-06 19: 13: 23.272 bis 23.312 30,211/com.example.xuan.tictactoe D/OpenGLRenderer: Verwendung EGL_SWAP_BEHAVIOR_PRESERVED: true
04-06 19 : 13: 30.219 23272-23272/com.example.xuan.tictactoe D/Atlas: Validieren der Karte ...
04-06 19: 13: 30.245 23272-23312/com.beispiel.xuan.tictactoe I/Adreno -EGL: QUALCOMM Körperbau: 01/14/15, ab0075f, Id3510ff6dc
04-06 19: 13: 30,246 23.272-23.312/com.example.xuan.tictactoe I/OpenGLRenderer: Initialized EGL, Version 1.4
04-06 19: 13: 23.272 bis 23.312 30,267/com.example.xuan.tictactoe D/OpenGLRenderer: Aktivieren von Debug-Modus 0
04-06 19: 14: 40.950 23.272 bis 23.272/com.example. xuan.tictactoe D/test: onCreate
04-06 19: 14: 23.272 bis 23.272 40,956/com.example.xuan.tictactoe D/test: onCreate nach set view
04-06 19:14: 41.161 23272-24500/com.example.xuan.tictactoe E/AndroidRuntime: FATALE AUSNAHME: Thread-8231
Prozess: com.examp le.xuan.tictactoe, PID: 23272
java.lang.NullPointerException: Versuch virtuelle Methode 'VOID android.graphics.Canvas.drawColor (int)' zum Aufrufen auf einer null Objektreferenz
bei com.example.xuan.tictactoe.GameView.draw (GameView.java:135)
bei com.example.xuan.tictactoe.GameView.run (GameView.java:100)
bei java.lang .Thread.run (Thema.Java: 818)
NewGame
Aktivität
public class NewGame extends Activity {
GameView game_view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
game_view = new GameView(this);
setContentView(R.layout.activity_new_game);
}
// This method executes when the player starts the game
@Override
protected void onResume() {
super.onResume();
// Tell the gameView resume method to execute
game_view.resume();
}
// This method executes when the player quits the game
@Override
protected void onPause() {
super.onPause();
// Tell the gameView pause method to execute
game_view.pause();
}
// Start new activity
public void createInfo(View view) {
Intent intent = new Intent(this, PetInfo.class);
startActivity(intent);
}
}
GameView.java
public class GameView extends SurfaceView implements Runnable {
Thread game_thread = null;
// SurfaceHolder for Paint and Canvas in a thread
SurfaceHolder the_holder;
// Canvas and Paint objects
Canvas canvas;
Paint paint;
Bitmap dragon;
volatile boolean is_running;
long fps; // tracks the game frame rate
private long time_this_frame; // calculate the fps
float x_position = 0; // start position
float y_position = 0;
long frame_ticker = 0l;
// New variables for spritesheet
private int frame_count = 10; // How many frames are there on the sprite sheet?
private int sprite_width = 600;
private int sprite_height = 450;
private int current_frame = 0; // Start at the first frame - where else?
// A rectangle to define an area of the sprite sheet that represents 1 frame
private Rect frame_to_draw = new Rect(0, 0, sprite_width, sprite_height);
// A rect that defines an area of the screen on which to draw
RectF where_to_draw = new RectF(x_position, 0, x_position + sprite_width, sprite_height);
// Constructor methods
public GameView(Context context) {
super(context);
init(context);
}
public GameView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public GameView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
// Initialize ourHolder and paint objects
the_holder = getHolder();
the_holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
pause();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
resume();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
});
paint = new Paint();
// Load dragon from .png file
dragon = BitmapFactory.decodeResource(this.getResources(), R.drawable.gd10_spritesheet);
}
@Override
public void run() {
while (is_running) {
// Capture the current time in milliseconds in startFrameTime
long startFrameTime = System.currentTimeMillis();
update(); // Update the frame
draw(); // Draw the frame
// Calculate the fps this frame to time animations.
time_this_frame = System.currentTimeMillis() - startFrameTime;
if (time_this_frame >= 1) {
fps = 5000/time_this_frame;
}
}
}
// Everything that needs to be updated goes in here
// In later projects we will have dozens (arrays) of objects.
// We will also do other things like collision detection.
public void update() {
long game_time = System.currentTimeMillis();
if (game_time > (frame_ticker + fps)) {
frame_ticker = game_time;
current_frame++;
if (current_frame >= frame_count) {
current_frame = 0;
}
}
frame_to_draw.left = current_frame * sprite_width;
frame_to_draw.right = frame_to_draw.left + sprite_width;
}
// Draw the newly updated scene
public void draw() {
// Make sure our drawing surface is valid or we crash
if (the_holder.getSurface().isValid()) {
canvas = the_holder.lockCanvas(); // Lock the canvas ready to draw
canvas.drawColor(Color.argb(255, 144, 195, 212)); // Draw the background color
paint.setColor(Color.argb(255, 249, 129, 0)); // Choose the brush color for drawing
x_position = (float) (this.getWidth()/2.0 - frame_to_draw.width()/2.0);
y_position = (float) (this.getHeight()/4.0 - frame_to_draw.height()/2.0);
where_to_draw.set((int) x_position,
(int) y_position,
(int) x_position + sprite_width,
(int) y_position + sprite_height);
canvas.drawBitmap(dragon,
frame_to_draw,
where_to_draw, paint);
the_holder.unlockCanvasAndPost(canvas); // Draw everything to the screen
}
}
// If activity is paused/stopped shutdown our thread.
public void pause() {
is_running = false;
try {
game_thread.join();
} catch (InterruptedException e) {
Log.e("Error:", "joining thread");
}
game_thread = null;
}
// If activity is started then start our thread.
public void resume() {
is_running = true;
game_thread = new Thread(this);
game_thread.start();
}
}
activity_new_game.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.xuan.tictactoe.NewGame">
<com.example.xuan.tictactoe.GameView
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:text="OK"
android:onClick="createInfo"/>
</RelativeLayout>
Komische ist, dass ich einige Log in onCreate von PetInfo
setzen und das Log läuft, das heißt PetInfo
Aktivität erstellt, aber aus irgendwelchen Gründen wirft es Fehler auf dem Gewinde der vorherigen Aktivität (die NewGame
ist ' s GameView
).
Irgendeine Idee? Vielen Dank!
Ich denke, mit meinem Code, der Thread schließt Aufgaben und verbindet, bevor die neue Aktivität beginnt. Und die neue Aktivität wird tatsächlich ausgeführt, aber dann wirft die App Fehler auf den Thread. Hast du irgendwelche Vorschläge? –
Sie gaben mir also eine -1 für etwas, von dem Sie denken, dass es das tut? – TooManyEduardos
Ich habe dir keine -1 gegeben. –