views:

677

answers:

3

I am overriding the onCreateDialog and onPrepareDialog methods or the Dialog class.

I have followed the example from Reto Meier's Professional Android Application Development book, Chapter 5 to pull some XML data and then use a dialog to display the info.

I have basically followed it exactly but changed the variables to suit my own XML schema as follows:


@Override
public Dialog onCreateDialog(int id) {
  switch(id) {
    case (SETTINGS_DIALOG) :        
      LayoutInflater li = LayoutInflater.from(this);
      View settingsDetailsView = li.inflate(R.layout.details, null);

      AlertDialog.Builder settingsDialog = new AlertDialog.Builder(this);
      settingsDialog.setTitle("Provisioned Settings");         
      settingsDialog.setView(settingsDetailsView);
return settingsDialog.create();
  }
  return null;
}

@Override
public void onPrepareDialog(int id, Dialog dialog) {
  switch(id) {
    case (SETTINGS_DIALOG) :                  

String afpunText = "  ";

     if(setting.getAddForPublicUserNames() == 1){
      afpunText = "Yes";
     }
     else{
      afpunText = "No";
     }
      String Text = "Login Settings: " + "\n" 
                       + "Password: " + setting.getPassword()  + "\n" 
                       + "Server: " + setting.getServerAddress() + "\n";


      AlertDialog settingsDialog = (AlertDialog)dialog; 
settingsDialog.setTitle(setting.getUserName());

tv = (TextView)settingsDialog.findViewById(R.id.detailsTextView);
if (tv != null)
        tv.setText(Text);

      break;
  }
}

It works fine until I try changing the screen orientation, When I do this onPrepareDialog gets call but I get null pointer exceptions on all my variables.

The error still occurs even when I tell my activity to ignore screen orientation in the manifest.

So I presume something has been left out of the example in the book do I need to override another method to save my variables in or something?

I have now added the following:


@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
  // Save UI state changes to the savedInstanceState.
  // This bundle will be passed to onCreate if the process is
  // killed and restarted.
  savedInstanceState.putString("Username", setting.getUserName());
  savedInstanceState.putString("Password", setting.getPassword());
  savedInstanceState.putString("Server", setting.getServerAddress());

  super.onSaveInstanceState(savedInstanceState);
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
  super.onRestoreInstanceState(savedInstanceState);
  settings.clear();
  // Restore UI state from the savedInstanceState.
  // This bundle has also been passed to onCreate.
  username = savedInstanceState.getString("Username");
  password = savedInstanceState.getString("Password");
  serveraddress = savedInstanceState.getString("Server");


Settings setting = new Settings(username, password, serveraddress);
addNewSettings(setting);

}

But I'm still getting the Null Pointer exception

+1  A: 

When you change orientation, android restart your activity, you need to save the estate with

onSaveInstanceState

and recover with

savedInstanceState
JoaquinG
+2  A: 

I don't have Reto's book so I can't check the code, but if there is a mistake in the book you can contact him easily on Twitter to discuss it: http://twitter.com/retomeier

Remember that if the screen orientation changes, your activity is recreated. That means that any variables you set the last time around, which are not static, will be lost after the activity is recreated under the new orientation.

My guess is that you hit a NullPointerException here:

if(setting.getAddForPublicUserNames() == 1){

If so, it is most likely that some user action changes the "setting" variable to something other than null - you need to make sure this is set again when the activity is recreated.

The most standard method to store/retrieve the activity state between orientations is detailed here: http://stackoverflow.com/questions/151777/how-do-i-save-an-android-applications-state

seanhodges
Hi seanhodges, I followed the example in the stack overflow example you supplied, I have added my new code to my question but I am still getting the Null pointer on the exact line you mentioned - if(setting.getAddForPublicUserNames() == 1){
Donal Rafferty
Hmm, I would expect it to work now. Try sticking a breakpoint in your onRestoreInstanceState() method and make sure that "setting" is actually being set before the onPrepareDialog() method tries to use it...
seanhodges
It would appear that my setting object is the cause of the null pointers, It must not be getting created/saved or something? I changed all my variables to be within the class and removed the use of the setting object and the app runs fine now. Q the rest of the evening figuring out why my object isn't getting saved/created :(
Donal Rafferty
You might be doing a "setting = new Setting()" in the constructor of your Activity (which won't get called the second time). Make sure you have put "this.setting = setting" in your addNewSettings() method.
seanhodges
Excellent, Thanks for that!
Donal Rafferty
A: 

If you don't want the activity to be recreated when orientation changes. Insert the following line in the AndroidManifest.xml.

android:configChanges="keyboardHidden|orientation

example:

<activity android:name=".FABSLogin" android:label="@string/app_name" android:theme="@style/Theme.NoWindowTitle" android:noHistory="true" **android:configChanges="keyboardHidden|orientation**"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>

Viren Pushpanayagam