简体   繁体   English

为什么对象在RestoreInstanceState上引发nullPointerException?

[英]Why does an object throw nullPointerException on RestoreInstanceState?

I've got a TextView and ImageButton objects in my android app, they appear correctly when the app starts (onCreate), but when saveInstanceState() and restoreInstanceState() are called the compiler throws nullPointerException (even though their states are loaded properly) when I try to setText or anything for that matter. 我的Android应用程序中有一个TextView和ImageButton对象,它们在应用程序启动时正确显示(onCreate),但是当调用saveInstanceState()和restoreInstanceState()时,编译器将抛出nullPointerException(即使它们的状态正确加载),我尝试setText或其他任何事情。 I have some other ImageButtons that show correctly both times (on first onCreate, and when restoreInstanceState is called) so it puzzles me even further. 我还有一些其他的ImageButtons可以正确显示两次(第一次onCreate以及调用restoreInstanceState时),所以这使我更加困惑。

I had tried to create another instance of TextView, setText to it, and then set that TextView as the original, but it doesn't work. 我试图创建另一个TextView实例,将setText设置为它,然后将该TextView设置为原始实例,但是它不起作用。

public class MainActivity extends AppCompatActivity {
    private TextView score;
    private TextView labelPoints;
    private ImageButton finQuest;
    private int langFlag = 0;
    private PowerManager.WakeLock wakeLock;
    private int points = 0;
    private ListenerQuestionChooser lqc;
    //saving and loading the instanceState of the buttons bellow works perfectly
    private ImageButton btn1;
    private ImageButton btn2;
    private ImageButton btn3;
    private ImageButton btn4;
    private ImageButton btn5;
    private ImageButton btn6;

    @SuppressLint("InvalidWakeLockTag")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "My Lock");
        wakeLock.acquire();

        setContentView(R.layout.activity_main);

        labelPoints = findViewById(R.id.total_score);
        finQuest = findViewById(R.id.btn_finanswer);
        score = findViewById(R.id.text_points); 
        btn1 = findViewById(R.id.btn1);
        btn2 = findViewById(R.id.btn2);
        btn3 = findViewById(R.id.btn3);
        btn4 = findViewById(R.id.btn4);
        btn5 = findViewById(R.id.btn5);
        btn6 = findViewById(R.id.btn6);
        lqc = new ListenerQuestionChooser(this, this);

        if (savedInstanceState != null) {
            this.loadSettings(savedInstanceState);
        }

        btn1.setOnClickListener(lqc);
        btn2.setOnClickListener(lqc);
        btn3.setOnClickListener(lqc);
        btn4.setOnClickListener(lqc);
        btn5.setOnClickListener(lqc);
        btn6.setOnClickListener(lqc);

        if (getLangFlag() == 0){
            labelPoints.setVisibility(View.INVISIBLE);
            TextView s = findViewById(R.id.text_points);
            setScore(s);
            score.setVisibility(View.INVISIBLE);
        }else{
            //I have tried to directly set text to the original TextView, it didn't work
            //Then I tried like this, still doesn't work
            TextView s = findViewById(R.id.text_points);
            s.setText(getPoints()); //throws null pointer here
            setScore(s);
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        //there are other things saved here that are not relevant to the question, which save and load perfectly
        if (getFinQuest().getVisibility()==View.VISIBLE) {
            outState.putInt(STATE_FINAL_BUTTON, 1);
        } else{
            outState.putInt(STATE_FINAL_BUTTON, 0);
        }
        if (btn1.getVisibility() == View.INVISIBLE) {
            outState.putInt(STATE_BUTTON_01, 1);
        } else{
            outState.putInt(STATE_BUTTON_01, 0);
        }
        if (btn2.getVisibility() == View.INVISIBLE) {
            outState.putInt(STATE_BUTTON_02, 1);
        } else{
            outState.putInt(STATE_BUTTON_02, 0);
        }
        if (btn3.getVisibility() == View.INVISIBLE) {
            outState.putInt(STATE_BUTTON_03, 1);
        }else{
            outState.putInt(STATE_BUTTON_03, 0);
        }
        if (btn4.getVisibility() == View.INVISIBLE) {
            outState.putInt(STATE_BUTTON_04, 1);
        }else{
            outState.putInt(STATE_BUTTON_04, 0);
        }
        if (btn5.getVisibility() == View.INVISIBLE) {
            outState.putInt(STATE_BUTTON_05, 1);
        }else{
            outState.putInt(STATE_BUTTON_05, 0);
        }
        if (btn6.getVisibility() == View.INVISIBLE) {
            outState.putInt(STATE_BUTTON_06, 1);
        }else{
            outState.putInt(STATE_BUTTON_06, 0);
        }
        outState.putCharSequence(STATE_USERNAME_LANG, String.valueOf(langFlag));
          outState.putInt(STATE_POINTS, getPoints());
   }

   private void loadSettings(Bundle savedInstanceState){
        //I printed logs after each of these lines and the values are loaded perfectly
        CharSequence lFlag = savedInstanceState.getCharSequence(STATE_USERNAME_LANG);
        setLangFlag(Integer.parseInt(lFlag.toString()));
        int butFin = savedInstanceState.getInt(STATE_FINAL_BUTTON);
        if (butFin == 1) {
            finQuest.setVisibility(View.VISIBLE);
        }
        int but01 = savedInstanceState.getInt(STATE_BUTTON_01);
        if (but01 == 1) {
            btn1.setVisibility(View.INVISIBLE);
        }
        int but02 = savedInstanceState.getInt(STATE_BUTTON_02);
        if (but02 == 1) {
            btn2.setVisibility(View.INVISIBLE);
        }
        int but03 = savedInstanceState.getInt(STATE_BUTTON_03);
        if (but03 == 1) {
            btn3.setVisibility(View.INVISIBLE);
        }
        int but04 = savedInstanceState.getInt(STATE_BUTTON_04);
        if (but04 == 1) {
            btn4.setVisibility(View.INVISIBLE);
        }
        int but05 = savedInstanceState.getInt(STATE_BUTTON_05);
        if (but05 == 1) {
            btn5.setVisibility(View.INVISIBLE);
        }
        int but06 = savedInstanceState.getInt(STATE_BUTTON_06);
        if (but06 == 1) {
            btn6.setVisibility(View.INVISIBLE);
        }
        int poeni = savedInstanceState.getInt(STATE_POINTS);
        setPoints(poeni);
   }
    public int getPoints() {
        return points;
    }

    public void setPoints(int points) {
        this.points = points;
    }
    public TextView getScore() {
        return score;
    }

    public void setScore(TextView score) {
        this.score = score;
    }
}

FINAL EDIT: After approximately 16 hours of banging my head against the wall, trying various things (both logical and illogical) and printing logs on every step, I had solved the problem. 最终编辑:将我的头撞到墙上约16个小时,尝试各种事情(逻辑和不逻辑的)并在每一步上打印日志,我已经解决了这个问题。 So here's the solution (I still don't understand why other objects work perfectly without this and these objects require it, but hey, as long as it works I down with it). 因此,这就是解决方案(我仍然不明白为什么其他对象在没有此功能的情况下会完美运行,而这些对象却需要它,但是,嘿,只要它可以工作,我就会拒绝它)。

if (lqc == null) {
        lqc = new ListenerQuestionChooser(this, this);
    }

    if (savedInstanceState != null) {
        this.loadSettings(savedInstanceState);
    }

    if (finQuest == null) {
        try {
            finQuest = findViewById(R.id.btn_finansfer);
            finQuest.setOnClickListener(lqc);
            if (ListenerQuestionChooser.getCorrectAnswer() > 0) {
                finQuest.setVisibility(View.VISIBLE);
            } else {
                finQuest.setVisibility(View.INVISIBLE);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    if (labelPoints == null) {
        labelPoints = findViewById(R.id.total_score);
        score = findViewById(R.id.text_points);
        try {
            ss = new StringSetter(this);
            if (getLangFlag() == 0) {
                labelPoints.setVisibility(View.INVISIBLE);
                score.setVisibility(View.INVISIBLE);
            } else {
                score.setText(String.valueOf(getPoints()));
                labelPoints.setText(ss.podesiPromenljivu(brPoena, getLanguage()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 }

This is the log I get: 这是我得到的日志:

09-08 17:55:19.317 8848-8848/? 09-08 17:55:19.317 8848-8848 /? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.quizme, PID: 8848 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.quizme/com.example.quizme.MainActivity}: java.lang.NullPointerException at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2338) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390) at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3930) at android.app.ActivityThread.access$900(ActivityThread.java:151) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1327) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:5292) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824) at com.android.internal.os.ZygoteInit.main(Zygo E / AndroidRuntime:致命例外:主进程:com.example.quizme,PID:8848 java.lang.RuntimeException:无法启动活动ComponentInfo {com.example.quizme / com.example.quizme.MainActivity}:java.lang。在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2338)在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)在android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3930)在NullPointerException .android.app.ActivityThread.access $ 900(ActivityThread.java:151).android.os.Handler.dispatchMessage(Handler.java:110).ActivityThread $ H.handleMessage(ActivityThread.java:1327) .loop(Looper.java:193)at android.app.ActivityThread.main(ActivityThread.java:5292)at java.lang.reflect.Method.invokeNative(本机方法)at java.lang.reflect.Method.invoke(Method .java:515)com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:824)com.android.internal.os.ZygoteInit.main(Zygo teInit.java:640) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.NullPointerException at com.example.quizme.MainActivity.onCreate(MainActivity.java:256) at android.app.Activity.performCreate(Activity.java:5264) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2302) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390) at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3930) at android.app.ActivityThread.access$900(ActivityThread.java:151) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1327) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:5292) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$M 在dalvik.system.NativeStart.main处运行teInit.java:640)(本机方法)由以下原因导致:位于com.example.quizme.MainActivity.onCreate(MainActivity.java:256)处的java.lang.NullPointerException。在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)在perform.Create(Activity.java:5264)在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java)在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2302) :2390),位于android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3930),位于android.app.ActivityThread.access $ 900(ActivityThread.java:151),位于android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1327) )的android.os.Handler.dispatchMessage(Handler.java:110)的android.os.Looper.loop(Looper.java:193)的android.app.ActivityThread.main(ActivityThread.java:5292)的java.lang .reflect.Method.invokeNative(本机方法)位于com.android.internal.os.ZygoteInit $ M处的java.lang.reflect.Method.invoke(Method.java:515) ethodAndArgsCaller.run(ZygoteInit.java:824) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640) at dalvik.system.NativeStart.main(Native Method) ethodAndArgsCaller.run(ZygoteInit.java:824)在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)在dalvik.system.NativeStart.main(本机方法)

After approximately 16 hours of banging my head against the wall, trying various things (both logical and illogical) and printing logs on every step, I had solved the problem. 在将我的头撞在墙上约16个小时之后,尝试了各种尝试(逻辑和非逻辑)并在每一步上打印了日志,我已经解决了这个问题。 So here's the solution (I still don't understand why other objects work perfectly without this and these objects require it, but hey, as long as it works I down with it). 因此,这就是解决方案(我仍然不明白为什么其他对象在没有此功能的情况下会完美运行,而这些对象却需要它,但是,嘿,只要它可以工作,我就会拒绝它)。

if (lqc == null) {
    lqc = new ListenerQuestionChooser(this, this);
}

if (savedInstanceState != null) {
    this.loadSettings(savedInstanceState);
}

if (finQuest == null) {
    try {
        finQuest = findViewById(R.id.btn_finansfer);
        finQuest.setOnClickListener(lqc);
        if (ListenerQuestionChooser.getCorrectAnswer() > 0) {
            finQuest.setVisibility(View.VISIBLE);
        } else {
            finQuest.setVisibility(View.INVISIBLE);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

if (labelPoints == null) {
    labelPoints = findViewById(R.id.total_score);
    score = findViewById(R.id.text_points);
    try {
        ss = new StringSetter(this);
        if (getLangFlag() == 0) {
            labelPoints.setVisibility(View.INVISIBLE);
            score.setVisibility(View.INVISIBLE);
        } else {
            score.setText(String.valueOf(getPoints()));
            labelPoints.setText(ss.podesiPromenljivu(brPoena, getLanguage()));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

This is obviously not the complete source so we can only guess. 这显然不是完整的资料,因此我们只能猜测。 It looks like the first time you create this activity langFlag is set to 0. After you read it from bundle it must be a different value since you get into the else block. 看起来像是第一次创建此活动时langFlag设置为0。从包中读取后,它必须是另一个值,因为您进入else块。 We don't know what is the getPoints - it is mentioned only once in place where you get NPE. 我们不知道什么是getPoints-在获得NPE的地方仅提及一次。 So, it looks that getPoints is null but we can't tell why from the code you attached. 因此,看起来getPoints为null,但是我们无法从您附加的代码中得知原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM