Dogulas
Dogulas

Reputation: 47

onActivityResult called too early

I have a synchronicity problem. I have searched and cannot find a question with the same conditions as mine. Pointers are welcome.

Android 4.1.2 on Eclipse 4.2.1

I have two activities; let's call them ListActivity and DetailActivity. On a button press on ListActivity, I start DetailActivity. When the user makes changes to data in the DetailActivity and then clicks the back button, I want to do two things. First, I want to save changes to the database if a dirty flag is true. Second, I want to return an Intent to the onActivityResult() method of the ListActivity.

The problem is one of timing. Since I want to do database updating, I read that it is best practices to do this in the onStop() method of the DetailActivity. Right after I update the database I set up the Intent and call the setReult() method in the DetailActivity.

_resultIntent = new Intent();  
_resultIntent.putExtra(ListActivity .DETAIL_RESULT, _currentData);  
Log.d("ListActivity.setUpReturn()", "checkpoint");  
setResult(Activity.RESULT_OK, _resultIntent);  

The onActivityResult() method of the ListActivity is called before I have a chance to set the result. I placed Log calls throughout and what appears to happen is the following:

1) The user is in the DetailActivity and changes some data setting the dirty flag to true.
2) The user clicks the system back button.
3) The DetailActivity disappears from the screen.
4) The ListActivity re-appears.
5) The Log notes the onActivityResult(), onRestart(), onStart(), and onResume() methods of ListActivity execute in that order
6) Some other stuff is logged.
7) The Log FINALLY notes that the onStop() method of the DetailActiviy executes.

This means that by the time I am updating the database and setting up the result Intent, the calling activity has already gone past the point of using it.

I'd rather not constantly update the database. I'd rather put this into the onStop() method like the best practices says, but I don't know how to get around the issue of timing. Any suggestions? Am I doing something obviously wrong?

Upvotes: 2

Views: 1386

Answers (4)

Ali Imran
Ali Imran

Reputation: 9217

Check that did you make your activity as a SingleInstance if yes then make it to SingleTop

Upvotes: 3

Dogulas
Dogulas

Reputation: 47

It turns out the best solution for me was from PravinCG. I will use this as a pattern in the future.

@Override
public void onBackPressed() {
    Log.d("DetailActivity.onBackPressed()", "checkpoint");
    if (_currentDataIsDirty) {
        DoDatabaseWork(_currentData);
    }
    _resultIntent = new Intent();
    _resultIntent.putExtra(ListActivity .DETAIL_RESULT, _currentData);
    setResult(Activity.RESULT_OK, _resultIntent);
    super.onBackPressed();
}

Dogulas

Upvotes: 0

PravinCG
PravinCG

Reputation: 7708

I would rather rely on event based code logic rather than on probability. You could try the following.

*1) The user is in the DetailActivity and changes some data setting the dirty flag to true. 2) The user clicks the system back button.*

Override the onBackPressed method and perform your database operation right there and once the DB operation is performed you can call the super.onBackPressed() method and let the Android Activity stack take over. Mind you DB operation could be time consuming and hence it is also recommended to use AsyncTask with callback and only then call finish().

Upvotes: 2

user219882
user219882

Reputation: 15844

That's because onPause() is called right after the activity loses focus. The onStop() however is called when the activity is going to be destroyd (usually when there is not enough memory). So put your code into the onPause() method and you should be fine...

Upvotes: 1

Related Questions