从Thread获得NullPointerException

时间:2012-12-20 14:28:26

标签: android multithreading nullpointerexception

我正在写一个小小的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;
            }
        }
    }



}
}

感谢您的帮助;)

4 个答案:

答案 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;

                }
        }
        }
        }

感谢大家激励我的解决方案! :)