onActivityResult isn't getting the proper result after returning because the activty that called it was re-created?

StackOverflow https://stackoverflow.com/questions/16837679

Pergunta

I have two activities: PictureList and AddPictures. From the activity PictureList I'm requesting an activity for result like this:

Intent myIntent = new Intent(PictureList.this, AddPictures.class);
Bundle b = new Bundle();
b.putInt("iEntry", clickCounter);
b.putBoolean("bAddPicture", true);
b.putBoolean("bEditPicture", false);
myIntent.putExtras(b);
startActivityForResult(myIntent,1);

I'm also implementing the corresponding onActivityResult here:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      if (requestCode == 1) {
         if(resultCode == RESULT_OK){        
             iReturnedEntry = data.getIntExtra("iReturnedEntry", 0);
         }
         if (resultCode == RESULT_CANCELED) {    
         }
      }
    }
}

On the other activity, AddPictures, receives the parameters:

Bundle b = getIntent().getExtras();
iEntry = b.getInt("iEntry");
bAddPicture = b.getBoolean("bAddPicture", false);
bEditPicture = b.getBoolean("bEditPicture", false);

and when it has to return it does it like this:

Intent returnIntent = new Intent();
returnIntent.putExtra("iReturnedEntry", iEntry);
setResult(RESULT_OK,returnIntent);     

Normally the application works fine, but very often it happens that the result isn't stored. I think that because of some memory management or other reason the PictureList activity is re-creating, or it is calling the onCreate method again after returning from the activity AddPictures and because of this the onActivityResult isn't working. How can I solve this issue?

Foi útil?

Solução

If you are waiting for a result from another activity the best thing is to save the parameters as shared preferences and then load them back in the previous activity during onResume. In this way the data won't be lost due to the re-create of the activity that contains the onActivityResult.

Then, for the first activity PictureList, the code changed into this:

bPictureRequested = true;
bPictureReceived = false;
appSharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
preferencesEditor = appSharedPreferences.edit();
preferencesEditor.putBoolean("bPictureReceived", bPictureReceived);
preferencesEditor.commit();

Intent myIntent = new Intent(PictureList.this, AddPictures.class);
Bundle b = new Bundle();
b.putInt("iEntry", clickCounter);
b.putBoolean("bAddPicture", true);
b.putBoolean("bEditPicture", false);
myIntent.putExtras(b);
startActivity(myIntent);

and into onResume I added the following lines in order to get the result:

if(bPictureRequested){
        appSharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        bPictureReceived = appSharedPreferences.getBoolean("bPictureReceived", false);
        if(bPictureReceived){
                iReturnedEntry = appSharedPreferences.getInt("iReturnedEntry", 0);
                // Reset the flags
                bPictureRequested = false;
                bPictureReceived = false;
                preferencesEditor = appSharedPreferences.edit();
                preferencesEditor.putBoolean("bPictureReceived", bPictureReceived);
                preferencesEditor.commit();
        }
}

Now, for the other activity AddPictures I left the same part that gets the previous parameters by value but changed the way it returs de data using shared preferences:

appSharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
preferencesEditor = appSharedPreferences.edit();
preferencesEditor.putBoolean("bPictureReceived", true);
preferencesEditor.putInt("iReturnedEntry", iEntry);
preferencesEditor.commit();
finish();

Now everything is working fine.

Outras dicas

Yes, activities can get recreated by Android, usually because it needed the memory while the activity was suspended.

Read up on the Activity lifecycle here and use the onPause() and onResume() methods to save and restore the state of your PictureList activity as the activity is suspended and resumed.

FWIW the same is true of Fragments except that they get created and destroyed even more frequently (for example when you rotate the device between landscape and portrait). Understanding the activity and fragment lifecycle, and working with it correctly, is vital to writing a well behaved application.

For example, when your smartphone switches from portrait to landscape mode, your activity is destroyed and recreated, it is necessary to back up data or it will be reseted.

for AddPictures class, try to save your data in onSaveInstanceState(Bundle outState) method from Activity et retrieve them in onCreate() method. Theses method restore your data if your Activity is recreated.

Example:

@Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("iReturnedEntry", iEntry);
    }

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null) {
            String dataSaved = savedInstanceState.getString("iReturnedEntry");
            Log.v("HelloWorldActivity", "iReturnedEntry=" + dataSaved);
        }

    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top