2012-12-20 41 views
1

我在寫一個小小的Android遊戲。它應該顯示一個隨機的4個動物序列,我將其實現爲ImageButtons。用戶必須記住這個序列並在之後重複。從線程得到NullPointerException

我現在的問題是Imagebuttons如何顯示的正確時機。

我得到了下面的NullPointerException,並找不到原因。也許任何人都可以幫忙!?

繼承人我主要活動:

package lichtenberger.paul; 

import java.util.Random; 

import android.app.Activity; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.widget.ImageButton; 
import android.widget.TextView; 

public class Game extends Activity { 

    int Reihenfolge[] = new int[40]; 

    Random generator = new Random(); 


    public final int CAT = 0; 
    public final int MAN = 1; 
    public final int BIRD = 2; 
    public final int SHEEP = 3; 
    public Handler handler; 
    public Thread AnimalThread; 
    {for(int i = 0; i<40; i++)Reihenfolge[i]=generator.nextInt(4);} 


    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_game); 

     final ImageButton cat = (ImageButton)findViewById(R.id.catButton); 
     final ImageButton sheep = (ImageButton)findViewById(R.id.sheepButton); 
     final ImageButton man = (ImageButton)findViewById(R.id.manButton); 
     final ImageButton bird = (ImageButton)findViewById(R.id.birdButton); 
     final TextView score = (TextView)findViewById(R.id.scoreNTV); 

     handler = new Handler(){ 

      @Override 

      public void handleMessage(Message msg){ 

       switch (msg.what) { 
       case 0: 
        cat.setVisibility(1); 
        man.setVisibility(0); 
        bird.setVisibility(0); 
        sheep.setVisibility(0); 
        break; 
       case 1: 
        man.setVisibility(1); 
        bird.setVisibility(0); 
        sheep.setVisibility(0); 
        cat.setVisibility(0); 
        break; 
       case 2: 
        bird.setVisibility(1); 
        sheep.setVisibility(0); 
        cat.setVisibility(0); 
        man.setVisibility(0); 
        break; 
       case 3: 
        sheep.setVisibility(1); 
        cat.setVisibility(0); 
        man.setVisibility(0); 
        bird.setVisibility(0); 
        break; 
       } 

      } 
     };   
      ShowSequence show = new ShowSequence(); 
      Thread showSeq = new Thread(show); 
      showSeq.start(); 

     }; 

} 

我的線程類:

package lichtenberger.paul; 

public class ShowSequence extends Game implements Runnable{  
    @Override 
    public void run() {     
     show(); 
    } 

    private void show() { 

     for(int i = 0; i<40; i++){ 
     switch (Reihenfolge[i]) { 
     case 0: 
       try { 
       // this pauses the Thread: Alternative to doing stuff... 
       Thread.sleep(2000); 

       handler.sendEmptyMessage(CAT); 
       } catch (InterruptedException e) { 
       e.printStackTrace();} 
       break; 

     case 1: 
      try { 
       // this pauses the Thread: Alternative to doing stuff... 
       Thread.sleep(2000); 

       handler.sendEmptyMessage(MAN); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      break; 

     case 2: 
      try { 
       // this pauses the Thread: Alternative to doing stuff... 
       Thread.sleep(2000); 

       handler.sendEmptyMessage(BIRD); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      break; 

     case 3: 
      try { 
       // this pauses the Thread: Alternative to doing stuff... 
       Thread.sleep(2000); 

       handler.sendEmptyMessage(SHEEP); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 

     default: 
      break; 
     } 
    } 
}} 

和我的logcat:

12-20 15:20:34.974: ERROR/AndroidRuntime(598): FATAL EXCEPTION: Thread-75 
12-20 15:20:34.974: ERROR/AndroidRuntime(598): java.lang.NullPointerException 
12-20 15:20:34.974: ERROR/AndroidRuntime(598):  at lichtenberger.paul.ShowSequence.show(ShowSequence.java:50) 
12-20 15:20:34.974: ERROR/AndroidRuntime(598):  at lichtenberger.paul.ShowSequence.run(ShowSequence.java:10) 
12-20 15:20:34.974: ERROR/AndroidRuntime(598):  at java.lang.Thread.run(Thread.java:856) 

編輯:

整個代碼在一個活動沒有工作:

package lichtenberger.paul; 

import java.util.Random; 

import android.app.Activity; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.widget.ImageButton; 
import android.widget.TextView; 

public class Game extends Activity { 

    int Reihenfolge[] = new int[40]; 

    Random generator = new Random(); 
    public ImageButton cat; 
    public ImageButton man; 
    public ImageButton bird; 
    public ImageButton sheep; 
    public TextView score; 
    private static Handler handler; 
    public final int CAT = 0; 
    public final int MAN = 1; 
    public final int BIRD = 2; 
    public final int SHEEP = 3; 
    public Runnable showAnimal; 
    public Thread AnimalThread; 
    {for(int i = 0; i<40; i++)Reihenfolge[i]=generator.nextInt(4);} 


    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_game); 

     setupUI(); 
     showSequence(); 
     initHandler(); 
    } 



    public void showSequence() { 

       showAnimal = new showAnimal(); 
       AnimalThread = new Thread(showAnimal); 
       AnimalThread.start(); 


    } 



    public void setupUI() { 

     cat = (ImageButton)findViewById(R.id.catButton); 
     sheep = (ImageButton)findViewById(R.id.sheepButton); 
     man = (ImageButton)findViewById(R.id.manButton); 
     bird = (ImageButton)findViewById(R.id.birdButton); 
     score = (TextView)findViewById(R.id.scoreNTV); 

    } 

    private void initHandler() { 
     handler = new Handler() { 
      @Override 
      public void handleMessage(Message msg) { 
       switch (msg.what) { 
       case CAT: 
        cat.setVisibility(1); 
        man.setVisibility(0); 
        bird.setVisibility(0); 
        sheep.setVisibility(0); 
        break; 
       case MAN: 
        man.setVisibility(1); 
        bird.setVisibility(0); 
        sheep.setVisibility(0); 
        cat.setVisibility(0); 
        break; 
       case BIRD: 
        bird.setVisibility(1); 
        sheep.setVisibility(0); 
        cat.setVisibility(0); 
        man.setVisibility(0); 
        break; 
       case SHEEP: 
        sheep.setVisibility(1); 
        cat.setVisibility(0); 
        man.setVisibility(0); 
        bird.setVisibility(0); 
        break; 
       } 
      } 
     }; 

    } 

    class showAnimal implements Runnable { 
     public void run() { 
      show(); 
     } 

     private void show() { 

      for(int i = 0;i<40;i++){ 

      switch (Reihenfolge[i]) { 

      case 0: 
       try { 
        // this pauses the Thread: Alternative to doing stuff... 
        Thread.sleep(2000); 

        handler.sendEmptyMessage(CAT); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       break; 

      case 1: 
       try { 
        // this pauses the Thread: Alternative to doing stuff... 
        Thread.sleep(2000); 

        handler.sendEmptyMessage(MAN); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       break; 

      case 2: 
       try { 
        // this pauses the Thread: Alternative to doing stuff... 
        Thread.sleep(2000); 

        handler.sendEmptyMessage(SHEEP); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       break; 
      case 3: 
       try { 
        // this pauses the Thread: Alternative to doing stuff... 
        Thread.sleep(2000); 

        handler.sendEmptyMessage(BIRD); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       break; 
      } 
     } 
    } 



} 
} 

感謝您的幫助;)

+0

ShowSequence類的第50行是什麼? – ademar111190

+0

該錯誤總是發送消息給處理程序的線路上。在這種情況下,它是:handler.sendEmptyMessage(BIRD); –

+1

你的類層次結構有點奇怪。在''Game.onCreate''中,你實例化''新的ShowSequence'',它擴展了''Game'',並創建了新的''Activity''(它永遠不會獲得它的''onCreate''稱爲btw)。也許你應該把''Runnable''寫成''Game''內的私人類而不是? – harism

回答

2

問題是你有2個獨立的對象 - Game的實例具有非空處理程序。具有空處理程序的ShowSequence的實例。您不應該從Game繼承ShowSequecne。它不會自動獲得所有Game的變量,您應該在Game中將ShowSequence作爲@harism建議的內部類別。 或者您必須在構造函數中明確地設置ShowSequence中的所有變量,或者在創建之後立即設置所有變量。

+0

我已經試圖把它作爲遊戲中的內部類。但是它會一次顯示所有4張圖像,而不是以延遲2秒的順序顯示:/ –

+0

@PaulLich您完全可以避免線程。使用[sendEmptyMessageDelayed](http://developer.android.com/reference/android/os/Handler.html#sendEmptyMessageDelayed%28int,%20long%29)內部處理程序的'handleMessage'方法發送空消息給自己,延遲時間爲2000。 –

+0

好的,謝謝。 sendEmptyMessageDelayed工作。但實際問題是我在調試時發現的另一個問題。所有圖片同時出現的原因是在很短的時間內開始線索。我通過改變showSequence方法的每個循環後的delaytime來解決這個問題。我在我的問題下發布我的解決方案。 –

0

保羅,

您是否嘗試過製造 「處理器」 變量揮發性?您可以在工作線程(即運行「ShowSequence」可運行)的情況下訪問此變量,而不使用同步(同步關鍵字)。儘管你甚至可能想要考慮添加某種形式的同步(我沒有經過足夠的確定),但你至少應該確保從一個線程寫入'handler'對其他線程是可見的。揮發性限定符是實現這一點的一種方式。

祝你好運! PS:ShowSequence擴展了遊戲嗎?這反過來又擴展了活動?我認爲你需要檢查這個繼承樹以及..不知道你是否想要這個..

0

我不會從博弈innert的ShowSequence,你可以通過處理程序作爲一個參數

//活動

ShowSequence show = new ShowSequence(handler); 
      Thread showSeq = new Thread(show); 
      showSeq.start(); 

// Thread類

public class ShowSequence implements Runnable{ 
Handler handler = null; 

public ShowSequence(handler){ 
     this.handler = handler; 
} 
0

實際問題是我在調試時發現的另一個問題。所有圖片同時出現的原因是在很短的時間內開始線索。我通過改變showSequence方法的每個循環後的delaytime來解決這個問題。

因此,這裏是我的滿級現在:

package lichtenberger.paul; 

import java.util.Random; 

import android.app.Activity; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.view.View; 
import android.widget.ImageButton; 
import android.widget.TextView; 

public class Game extends Activity { 

    int Reihenfolge[] = new int[40]; 

    Random generator = new Random(); 


    public final int CAT = 0; 
    public final int MAN = 1; 
    public final int BIRD = 2; 
    public final int SHEEP = 3; 
    public final int PAUSE = 4; 
    public final int ALL = 5; 
    public int Zug = 40; 
    public int time = 0; 
    public Handler handler; 
    public Thread AnimalThread; 
    public ImageButton cat; 
    public ImageButton man; 
    public ImageButton bird; 
    public ImageButton sheep; 

    {for(int i = 0; i<40; i++)Reihenfolge[i]=generator.nextInt(4);} 


    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_game); 

     cat = (ImageButton)findViewById(R.id.catButton); 
     sheep = (ImageButton)findViewById(R.id.sheepButton); 
     man = (ImageButton)findViewById(R.id.manButton); 
     bird = (ImageButton)findViewById(R.id.birdButton); 
     final TextView score = (TextView)findViewById(R.id.scoreNTV); 

     handler = new Handler(){ 

      @Override 

      public void handleMessage(Message msg){ 

       switch (msg.what) { 
       case CAT: 
        cat.setVisibility(View.VISIBLE); 
        man.setVisibility(View.INVISIBLE); 
        bird.setVisibility(View.INVISIBLE); 
        sheep.setVisibility(View.INVISIBLE); 

        break; 
       case MAN: 
        man.setVisibility(View.VISIBLE); 
        bird.setVisibility(View.INVISIBLE); 
        sheep.setVisibility(View.INVISIBLE); 
        cat.setVisibility(View.INVISIBLE); 

        break; 
       case BIRD: 
        bird.setVisibility(View.VISIBLE); 
        sheep.setVisibility(View.INVISIBLE); 
        cat.setVisibility(View.INVISIBLE); 
        man.setVisibility(View.INVISIBLE); 

        break; 
       case SHEEP: 
        sheep.setVisibility(View.VISIBLE); 
        cat.setVisibility(View.INVISIBLE); 
        man.setVisibility(View.INVISIBLE); 
        bird.setVisibility(View.INVISIBLE); 

        break; 

       case PAUSE: 
        sheep.setVisibility(View.INVISIBLE); 
        cat.setVisibility(View.INVISIBLE); 
        man.setVisibility(View.INVISIBLE); 
        bird.setVisibility(View.INVISIBLE); 

       case ALL: 
        sheep.setVisibility(View.VISIBLE); 
        cat.setVisibility(View.VISIBLE); 
        man.setVisibility(View.VISIBLE); 
        bird.setVisibility(View.VISIBLE); 
       } 

      } 
     }; 

     time = 0; 
     Zug = 40; 
     showGameSeq(time, Zug); 
     } 



    public int showGameSeq(int time, int Zug) { 
     ShowSequence show; 
     Thread showSeq; 
     int x = 0; 

     for(int i = 1; i<=Zug; ++i, ++x){ 

       if(Reihenfolge[i-1]!=Reihenfolge[i-1]){ 

        show = new ShowSequence(Reihenfolge[i-1], time); 
        showSeq = new Thread(show); 
        showSeq.start(); 
        time = time + 1000;} 

       else{ 
        show = new ShowSequence(Reihenfolge[i-1], time); 
        showSeq = new Thread(show); 
        showSeq.start(); 
        time = time + 1000; 

        show = new ShowSequence(PAUSE, time); 
        showSeq = new Thread(show); 
        showSeq.start(); 
        time = time + 500; 

       } 
      } 


     if(x==Zug){ 
     show = new ShowSequence(ALL, time); 
     showSeq = new Thread(show); 
     showSeq.start(); 
     }else{}; 


     return time; 
    }; 



    private class ShowSequence implements Runnable{ 

     int which; 
     int time; 

     public ShowSequence(int which, int time) { 
      this.which = which; 
      this.time = time; 
     } 

     @Override 
     public void run() { 

      show(); 

     } 

     private void show() { 

       switch (which) { 
       case CAT: 

        handler.sendEmptyMessageDelayed(CAT, time); 
        break; 
       case MAN: 

        handler.sendEmptyMessageDelayed(MAN, time); 
        break; 
       case BIRD: 

        handler.sendEmptyMessageDelayed(BIRD, time); 
        break; 
       case SHEEP: 

        handler.sendEmptyMessageDelayed(SHEEP, time); 
        break; 

       case PAUSE: 

        handler.sendEmptyMessageDelayed(PAUSE, time); 
        break; 

       case ALL: 

        handler.sendEmptyMessageDelayed(ALL, time); 
        break; 

       } 
     } 
     } 
     } 

感謝大家鼓舞我的解決方案! :)

相關問題