[英]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.