簡體   English   中英

為什么對象在RestoreInstanceState上引發nullPointerException?

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

我的Android應用程序中有一個TextView和ImageButton對象,它們在應用程序啟動時正確顯示(onCreate),但是當調用saveInstanceState()和restoreInstanceState()時,編譯器將拋出nullPointerException(即使它們的狀態正確加載),我嘗試setText或其他任何事情。 我還有一些其他的ImageButtons可以正確顯示兩次(第一次onCreate以及調用restoreInstanceState時),所以這使我更加困惑。

我試圖創建另一個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;
    }
}

最終編輯:將我的頭撞到牆上約16個小時,嘗試各種事情(邏輯和不邏輯的)並在每一步上打印日志,我已經解決了這個問題。 因此,這就是解決方案(我仍然不明白為什么其他對象在沒有此功能的情況下會完美運行,而這些對象卻需要它,但是,嘿,只要它可以工作,我就會拒絕它)。

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();
        }
    }
 }

這是我得到的日志:

09-08 17:55:19.317 8848-8848 /? 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 在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)在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)在dalvik.system.NativeStart.main(本機方法)

在將我的頭撞在牆上約16個小時之后,嘗試了各種嘗試(邏輯和非邏輯)並在每一步上打印了日志,我已經解決了這個問題。 因此,這就是解決方案(我仍然不明白為什么其他對象在沒有此功能的情況下會完美運行,而這些對象卻需要它,但是,嘿,只要它可以工作,我就會拒絕它)。

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();
    }
}

這顯然不是完整的資料,因此我們只能猜測。 看起來像是第一次創建此活動時langFlag設置為0。從包中讀取后,它必須是另一個值,因為您進入else塊。 我們不知道什么是getPoints-在獲得NPE的地方僅提及一次。 因此,看起來getPoints為null,但是我們無法從您附加的代碼中得知原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM