2016-04-07 19 views
0

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!

Antwort

-1

Runnable = anderer/Hintergrund-Thread, nicht Haupt-Thread. Dies macht Code innerhalb von Runnable in der Lage, eine lange Zeit zu dauern, ohne den Haupt/UI-Thread zu sperren.

Dies bedeutet jedoch auch, dass Sie den Haupt-/UI-Thread nicht aus einem anderen/Hintergrundthread aktualisieren können. Sie können den UI-Thread nur aktualisieren, nachdem die Aktion Runnable abgeschlossen wurde und Sie den Block Runnable verlassen haben.

+0

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? –

+0

Sie gaben mir also eine -1 für etwas, von dem Sie denken, dass es das tut? – TooManyEduardos

+0

Ich habe dir keine -1 gegeben. –

Verwandte Themen