How to avoid data reload on android device back button - android

I am using android tab based application with TabGroupActivity, the application have a ListActivity "A" which drills down to a detail activity "D", on detail activity when i click device back button it navigate back to ListActivtiy "A" and relaods the data (ProgressBar shows progress on back button).
How can i avoid reloading of data on back buttuon ?
Any help would be appreciated.

Perhaps you can use onSaveInstanceState() to save what's needed to be saved and then restore your activity in onCreate()

If you look at the Activity LifeCycle :
When you go to another activity, and press back, it will call finish(). The first activity was on the onStop() method because it was no longer visible. So, when you come back to the first activity, it will call the method onStart(), and on Stop().
Try to overload this method without calling the super method (it might be a very bad idea).
You can also try to remember the position when you was (get the index of the current tab), and on the onResume() method, set the current tab to this index.
You just need an int attribute savedPosition in your listactivity.
private int savedPosition = -1;
#Override
protected void onPause() {
savedPosition = getListView().getFirstVisiblePosition();
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
if(savedPosition != -1) {
getList().setSelection(savedPosition);
}
}

Related

Override onSavedInstanceState: savedInstanceState object is always null

I have two activities (A and B). Activity A calls activity B. Activity B has Back (Up) button like this:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Now when this UP button is pressed, onCreate of activity A is again called. In the activity A, there is a classId variable (which I got from an Intent) which I want to retain. For this I have following code in my onCreate of activity A:
if (savedInstanceState == null)
{
Intent intent = getIntent();
classId = intent.getIntExtra("CLASS_ID", 0);
}
else
{
classId = savedInstanceState.getInt("CLASS_ID");
}
I have also overriden the onSavedInstanceState method:
#Override
protected void onSaveInstanceState(Bundle savedInstanceState)
{
savedInstanceState.putInt("CLASS_ID", classId);
super.onSaveInstanceState(savedInstanceState);
}
I am following this SO answer:
onCreate being called on Activity A in up navigation
The problem I am facing is that when I come again to activity A by passing back button in activity B, onCreate gets called and I found savedInstanceState to be NULL.
Edit:
Is there any other way to save my classId variable so that when I return again to activity A, I can use that?
Edit 2
If I set launch mode of my activity A to SingleTop in the manifest file, my issue gets resolved. Is it the right approach?
You should not suppose that onSaveInstanceState called each time you go to next activity.See the docs
This method is called before an activity may be killed so that when it comes back some time in the future it can restore its state. For example, if activity B is launched in front of activity A, and at some point activity A is killed to reclaim resources, activity A will have a chance to save the current state of its user interface via this method so that when the user returns to activity A, the state of the user interface can be restored via onCreate(Bundle) or onRestoreInstanceState(Bundle).
You may further consult with official docs here
Try this
public class SingletonHolder {
//your id here as what data type you want
private static SingletonHolder instance;
public static SingletonHolder getInstance() {
if (instance == null) {
instance = new SingletonHolder();
}
return instance;
}
//set getter setter here
}
If not successfull feel free to comment
I changed the launchMode of the activity A to singleTop in the mainfest file like this:
android:launchMode="singleTop"
I followed this question on SO: Setting launchMode="singleTask" vs setting activity launchMode="singleTop"
By using this approach, activity A is not destroyed and when I just finish the activity B or click UP navigation in activity B, the existing instance of activity A is launched again.

Bundle savedInstanceState is always null

I have two different activities, in the first one I enter some info into some EditTexts, I then go to the second activity, but when I return, the text that was on EditTexts in the first activity are gone.
Here is the OnCreate() for the first activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_frm_recetas);
txtClient = (EditText) findViewById(R.id.txtNombreCliente);
if(savedInstanceState != null){
String client = savedInstanceState.getString("Client");
txtClient.setText(client);
}
}
I'm using the onSaveInstanceState method to save the info
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
String x = txtClient.getText().toString();
savedInstanceState.putString("Client", x);
super.onSaveInstanceState(savedInstanceState);
}
When doing a debug, I can see the savedInstanceState Bundle has indeed been filled in the onSaveInstanceState method, but in the OnCreate in shows null.
Maybe I have to add something in the second activity? I currently don't have anything in there other than a button that takes me back to the first activity.
You need to call super.onSaveInstanceState(savedInstanceState); as the first line in onSaveInstanceState method.
Next you need to put
if(savedInstanceState != null) {
String client = savedInstanceState.getString("Client");
txtClient.setText(client);
}
into the onRestoreInstanceState method. onCreate is only called when re-drawing the app.
It shows null because onCreate is called only when that activity is first created, when you return back from the second activity, it resumes your first activity..try showing it on onResume() method
My guess is that the first activity hasn't been destroyed, so onCreate is never called when you navigate back to first activity
I guess onCreate is called when aactivity is going to load into memory, and at that time activity does not contain any thing . thats why it always return null.
to save data you have onsaveinstance method and to restore you have onrestoreinstance method.
onSaveInstanceState() is a method used to store data before pausing the activity.
onRestoreInstanceState() is method used to retrieve that data back.

onCreate being called on Activity A in up navigation

So I have an Activity A and an Activity B. I want Activity A to be able to navigate to Activity B with the press of a button. That works, but when I use the up navigation(the home button in the action bar) to navigate back to Activity A, onCreate() is called again and the old information that the user typed in is lost.
I've seen: onCreate always called if navigating back with intent, but they used Fragments, and I'm hoping not to have to redesign the entire app to use fragments. Is there any way I can stop onCreate() from being called every time Activity A becomes active again?
This behavior is totally fine and wanted.
The system might decide to stop Activities which are in background to free some memory.
The same thing happens, when e.g. rotating the device.
Normally you save your instance state (like entered text and stuff) to a bundle and fetch these values from the bundle when the Activity is recreated.
Here is some standard code I use:
private EditText mSomeUserInput;
private int mSomeExampleField;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO inflate layout and stuff
mSomeUserInput = (EditText) findViewById(R.id.some_view_id);
if (savedInstanceState == null) {
// TODO instanciate default values
mSomeExampleField = 42;
} else {
// TODO read instance state from savedInstanceState
// and set values to views and private fields
mSomeUserInput.setText(savedInstanceState.getString("mSomeUserInput"));
mSomeExampleField = savedInstanceState.getInt("mSomeExampleField");
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// TODO save your instance to outState
outState.putString("mSomeUserInput", mSomeUserInput.getText().toString());
outState.putInt("mSomeExampleField", mSomeExampleField);
}
You can make the up button behave like pressing back, by overriding onSupportNavigateUp()
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
If you want to navigate from child to parent without recreating the parent (calling onCreate method), you may set the android:launchMode="singleTop" attribute for the parent activity in your AndroidManifest.xml

How to maintain the state of the activity?

I am trying to save the state of the activity in android.Basic scenario is there is 2 activities A and B.Activity A contains 2 edittext fields.User enters some value into it and moves to activity B via intent.When user comes back to Activity A (by intent i have provided a back button) I need to display those values in the 2 edittext fields that the user had entered (i.e maintain the state of activity A).Also i do not want to use shared preferences or make those fields as static.
I have used the following code but it does not help:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.manual_entry);
edittext1=(Edittext)findViewById(R.id.edittext1);
}
#Override
protected void onSaveInstanceState(Bundle savedInstanceState)
{
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString("cardvalue_saved_inst", value_card_manuallyentered);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
value_savedinstance = savedInstanceState.getString("cardvalue_saved_inst");
Log.e("value_savedinstance",""+value_savedinstance);
edittext1.setText(value_savedinstance);
}
In ActivityA, if you launch ActivityB and don't call finish() on yourself, when ActivityB finishes (when user presses BACK button or otherwise), ActivityA will be shown in the same state that it was in. This is just standard Android behaviour and you don't need to do anything special.
onRestoreInstanceState() is not called if a paused activity gets resumed (which is the usual case where ActivityA launches ActivityB and ActivityB then finishes).
onRestoreInstanceState() is only called if Android killed your activity (during orientation change for example) or killed your process. In that case, when the user returns to your activity, Android will create a new instance of the activity and then call onRestoreInstanceState().
I had to simply call finish() in Activity B and it worked.

Activity group does not refresh activities when back button is clicked

I have a tabhost on my application and I'm using an Activity group which handles 3 activities inside.
Example:
ActivityGroup Handles
A -> B -> C
When i start this activities i'm using the flag Intent.FLAG_ACTIVITY_CLEAR_TOP.
My problem is when the user goes from A->B->C and press back button, my B activity shows up, but it does not resume or reload or refresh. It has the same state as before.
For example if the user goes again to C, C is refreshed, but when from C goes back.... B is not.
On B I have implementend methods such as onResume, onStart, onReestart and debugging it the main thread never goes in there...
And i need to refresh B because C can make changes that change the content displayed on B.
I have googleled this for 3 days and I couldn't found a solution..
I had this problem too.
I was using ActivityGroup code based on this blog post.
When I pressed the back button the pervious View would load fine, but the activity associated with it would not fire the onResume().
I was using an extended activity with on overridden and public onResume().
I found this blog post, so tried casting the view as my extended activity and called onResume().
Bingo.
Edit.... here's some more detail...
public class YFIMenuListActivity extends ListActivity {
....
#Override
public void onResume() {
super.onResume();
}
....
}
onResume() is normally protected, but I override it and make it public so that my ActivityGroup can call it.
I only have extended list activities in this activity group (I was just playing around). If you have different activities, each will have to override onResume() and I guess you'd have to look at the type of context you got back from v.getContext() before casting and calling it.
My ActivityGroup looks something like this:
public class BrowseGroup extends ActivityGroup {
.....
#Override
protected void onResume() {
super.onResume();
// call current activity's onResume()
View v = history.get(history.size()-1);
YFIMenuListActivity currentActivity = (YFIMenuListActivity)v.getContext();
currentActivity.onResume();
}
....
}
I've managed to implement an expanded version of cousin_itt's approach.
In both of my activities being used within the activity group I changed onResume from :
protected void onResume()
to
public void onResume()
I then wrote the following onResume function in my ActivityGroup to manually fire off onResumes:
#Override
protected void onResume() {
super.onResume();
View v = history.get(history.size()-1);
MainPeopleView currentActivity = null;
try {
currentActivity = (MainPeopleView)v.getContext();
currentActivity.onResume();
}
catch ( ClassCastException e ) {
Log.e(TAG, e.toString());
}
ProfileView otherActivity = null;
try {
otherActivity = (ProfileView)v.getContext();
otherActivity.onResume();
}
catch ( ClassCastException e ) {
Log.e(TAG, e.toString());
}
}
I have to say, this feels like the worst android hack I've ever written. I'm never using activitygroup again.
((ReportActivity)getLocalActivityManager().getActivity("ReportActivity")).onResume();
ReportActivity is that name you want to back Activity
ps: v.getContext();
only return the ActivityGroup ,it can't invoke child Activity onResume
I have found that onFocusChanged(boolean hasFocus) is great for situations like ActivityGroup. This will fire, even if onResume() does not. I use it for a few of my apps that have TabHosts and ActivityGroups. Here you can force the refresh and insure that it always gets fired when your Activity regains the focus.
I hope you have write your refresh data code in this method onResume().

Categories

Resources