3

I'm getting a NullPointerException raised from a number of my users, and I'm unable to spot what the issue is, it is thrown on this line :

((Button)findViewById(R.id.speakEnglishButton)).setText("");

I'm unable to see what is wrong, the button exists with that Id, it compiles fine, works fine on my emulator and 2 devices, however I'm getting about 100 or so errors being posted in my developer console for users on this version.

Looking closer at the onResume :

@Override
protected void onResume()
{
    super.onResume();

    SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
    boolean isButtonLabelsEnabled = sp.getBoolean("isButtonLabelsEnabled", false);
    if (!isButtonLabelsEnabled)
    {
        ((Button)findViewById(R.id.speakEnglishButton)).setText("");
        ((Button)findViewById(R.id.speakFrenchButton)).setText("");
        ((Button)findViewById(R.id.speakSpanishButton)).setText("");
        ((Button)findViewById(R.id.speakGermanButton)).setText("");
        ((Button)findViewById(R.id.speakItalianButton)).setText("");
    }
    else
    {
        ((Button)findViewById(R.id.speakEnglishButton)).setText(getString(R.string.btnLblEnglish));
        ((Button)findViewById(R.id.speakFrenchButton)).setText(getString(R.string.btnLblFrench));
        ((Button)findViewById(R.id.speakSpanishButton)).setText(getString(R.string.btnLblSpanish));
        ((Button)findViewById(R.id.speakGermanButton)).setText(getString(R.string.btnLblGerman));
        ((Button)findViewById(R.id.speakItalianButton)).setText(getString(R.string.btnLblItalian));
    }
}

Essentially, all I'm doing is checking for a saved preference boolean, and depending on its value I'm either setting labels on buttons, or setting them to blanks.

Can anyone please advise?

Thanks

Jimmy
  • 16,123
  • 39
  • 133
  • 213

4 Answers4

7

I think the point is that when the user resumes the activity the layout is not set and thus a findViewById() has no 'anchor' to look for and thus returning null.

You may just move the call to setContentView() from onCreate to onResume (given that you are not referencing views in onCreate. For normal usage this makes no difference as in the Android lifecycle, onResumeis directly called after onCreate and before the user can interact with the activity.

Actually there is a bug in some applications where you visit an activity, then start a different one, perhaps leave the app for a different one, return and then return (via back button) to the first activity. Here all of a sudden you see a black screen. This is because the system "swapped" out the first activity and on returning only onResume is called, but not onCreate, so there is no chance to load the layout again there.

Heiko Rupp
  • 30,426
  • 13
  • 82
  • 119
  • How would one resolve this? Setting the content view in onResume such as `setContentView(R.layout.languageselection);` ? – Jimmy Jan 26 '12 at 20:40
  • This is not expected in the Activity life cycle. Is it addressed by some Android issue ticket? – Galya Sep 16 '16 at 11:37
  • To be honest, I don't recall details, as this answer was 4 years ago. I recall though that I indeed ran into this at the time being and was debugging it. I have no idea if there is a ticket. Or if that got fixed meanwhile in newer Android versions. – Heiko Rupp Sep 16 '16 at 14:53
3

Do all of those ((Button)findViewById(R.id.speakEnglishButton)).setText(""); .... in onCreate()

Add

private Button mSpeakEngButton;
.....

As class variables, initialize them in onCreate()

public void onCreate() {

   ....
   mSpeakEngButton = ((Button)findViewById(R.id.speakEnglishButton));
}

Later in code you can modify their values as mSpeakEngButton.setWhatever()

Maxim
  • 4,152
  • 8
  • 50
  • 77
  • 2
    But y are u getting this issue .. ?? – Code_Life Jan 29 '13 at 12:48
  • @MohitSharma I never tried it that way. I prefer to have references to controls I'm working with instead of using look-ups when I need to use any of them. – Maxim Jan 29 '13 at 14:50
  • 1
    but why this happened to him when onResume comes after onCreate callback? – Ewoks Mar 05 '15 at 12:58
  • 1
    I noticed this issue still happens on earlier versions of Android. It should not return null in onResume, since onResume comes after onCreate. Keeping a reference from onCreate is good practice though, findViewById does a linear lookup of views which uses a bit of time everytime a lookup is done. – afollestad Jul 28 '15 at 15:24
2

Most likely that's caused when

((Button)findViewById(R.id.speakEnglishButton));

returns null. This happens if such a resource cannot be found. Spontaneously one reason comes to my mind: You do not have default resources in your layout. That means: You must have at least one "default" layout, which applies for each language/orientation/... which should be placed in the folder "layout". Simply "layout".

poitroae
  • 21,129
  • 10
  • 63
  • 81
  • The layout XML file where these buttons reside, is in res/layout/mylayout.xml, therefore it would be the default right? – Jimmy Jan 26 '12 at 20:39
  • @Michael:couldn't get u can please explain more – Code_Life Jan 29 '13 at 13:27
  • @MohitSharma The blind guess I was making is, that you should place one `layout.xml` in your `layout` folder. You might have `layout-de`, `layout-land`, but not one that is simply named `layout` - without any postfixes. – poitroae Jan 29 '13 at 15:31
-1

If you keep setContentView() at onResume() instead of onCreate(), it will give inflate exception, I have tried this.

gIrL
  • 139
  • 4
  • 15