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. I have some other ImageButtons that show correctly both times (on first onCreate, and when restoreInstanceState is called) so it puzzles me even further.
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.
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. 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/? 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(ZygoteInit.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$MethodAndArgsCaller.run(ZygoteInit.java:824) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640) at dalvik.system.NativeStart.main(Native Method)