我正在写一个小小的Android游戏。它应该显示4个动物的随机序列,我实现为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();
};
}
My Thread Class:
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 :(得分:2)
问题是你有两个独立的对象 - Game
的实例具有非空处理程序。带有null处理程序的ShowSequence
实例。您不应该从ShowSequecne
继承Game
。它没有自动获取所有Game
个变量,你应该像@harism建议的那样在ShowSequence
中创建Game
内部类。
或者你必须在构造函数中明确地设置ShowSequence
中的所有变量,或者在创建它之后立即设置它们。
答案 1 :(得分:0)
保罗,
您是否尝试过使用“处理程序”变量 volatile ?您可以从工作线程(即运行“ShowSequence”runnable)访问此变量,而不使用同步( synchronized 关键字)。虽然您甚至可能想考虑添加某种形式的同步(我没有通过您的代码来做出这个决定),但至少应该确保从一个线程对“handler”的写入对其他线程是可见的。 volatile限定符是实现此目的的一种方法。
祝你好运!PS:ShowSequence扩展游戏?哪反过来扩展活动?我认为你还需要检查这个继承树..不确定你是否想要这个..
答案 2 :(得分:0)
我不会从游戏中获取ShowSequence,你可以将处理程序作为参数传递
//活性
ShowSequence show = new ShowSequence(handler);
Thread showSeq = new Thread(show);
showSeq.start();
//线程类
public class ShowSequence implements Runnable{
Handler handler = null;
public ShowSequence(handler){
this.handler = handler;
}
答案 3 :(得分:0)
实际问题是我在调试时发现的另一个问题。之所以出现所有图片的原因都是在很短的时间内启动线程。我通过改变showSequence方法的每个循环之后的延迟时间来解决这个问题。
所以现在这是我的全班:
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;
}
}
}
}
感谢大家激励我的解决方案! :)