Can I prevent app from resuming when it's killed by other process?
I have problem where I have Singleton class instance in Application class, it holds through app all my info about user and stuff gathered from API. When I open app from background(if it's killed by some process) I getting null on User Model(Picture paths, Name...) and app crushes.
Best way for me is app relaunch from launcher screen and get all info again, not resuming. Any solution for this?
Can I prevent app from resuming when it's killed by other process?
There are three ways an app can be "resumed", by a call to either onCreate, onStart, or onResume. Which one is called depends on how your app was "suspended", and what happens to it while in this state.
onResume follows onPause, which occurs when another app is brought to the foreground.
onStart (onRestart) follows onStop, which occurs when your app is no longer visible.
onCreate follows onPause or onStop if your memory is lost to another app.
When I open app from background(if it's killed by some process) I
getting Nulls on User Model(Picture paths, Name...)
Try persisting this user data in onSaveInstanceState
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString(STATE_USER, mUser);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
and restoring it in either onCreate or onRestoreInstanceState
static final String STATE_USER = "user";
private String mUser;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore user data from saved state
mUser = savedInstanceState.getString(STATE_USER);
}
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
text.setText(savedInstanceState.getString(STATE_USER));
}
Related
I created an app that uses ~10MB of RAM. It seems that when I start other apps and my app is in the background, it sometimes closes. I suspect this is because Android OS closes background apps for RAM management purposes (Phone have 1024MB of total RAM).
Is there any way that I can keep my app always running in the background programmatically or otherwise?
You cant keep your app alive in the background over the wishes of the OS. The best thing you can do is save and restore the state of your activities/fragments/views etc.
Recreating an Activity
static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
...
//saving
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
//restoring
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Always call the superclass first
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore value of members from saved state
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
} else {
// Probably initialize members with default values for a new instance
}
...
}
Use Service to run in Background.
Read more at Run Background Service.
I have an activity with "singleTask" mode. when this activity goes to background by taping on home key or other application, which methods will be called if it backs to foreground?
onCreate(Bundle savedInstanceState) with savedInstanceState != null
onRestoreInstanceState(Bundle savedInstanceState)
I think because there is one instance of this activity, it doesn't need to save and restore its state and it retain its own state always. am I right?
The sequence of methods that will be invoked is as follows,(in case when Android has killed the process hosting the Activity while the application was in the background, ) when Activity with singleTask mode comes in foreground:
1.onCreate 2.onStart 3.onRestoreInstanceState and 4.onResume
Below is sample code to demonstrate the concept: Activity Declaration in AndroidManifest.xml: <activity android:name="Second" android:launchMode="singleTask"></activity>
public class Second extends Activity {
EditText mEdit;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.imageview_not);
if (savedInstanceState!=null){
Log.e("onCreate of Actiity", savedInstanceState.getString("editval")); }
mEdit=(EditText) findViewById(R.id.editText1);
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.e("Second", "onResume");
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.e("Second", "onStart");
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
outState.putString("editval", mEdit.getText().toString());
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
Log.e("Second", "onRestoreInstanceState");
if (savedInstanceState!=null){
Log.e("onRestoreInstanceState", savedInstanceState.getString("editval"));
}
}
}
For illustration purpose, I am just using Edit Text and Android saves its state during configuration change, or when user press HOME etc.
Note that onSaveInstanceState(Bundle outState) is called before an activity may be killed so that when it comes back some time in the future it can restore its state using onRestoreInstanceState(Bundle savedInstanceState).
Also as mentioned by David in another Answer,If Android has not killed the process hosting the Activity, then bringing the task from the background to the foreground will not cause either onCreate() nor onRestoreInstanceState() to be called.
If Android has not killed the process hosting the Activity, then bringing the task from the background to the foreground will not cause either onCreate() nor onRestoreInstanceState() to be called. The Activity doesn't need to be created (it already exists) and the state doesn't need to be restored, because it hasn't been changed.
If, however, Android has killed the process hosting the Activity while the application was in the background, when the user returns to the application Android will create a new process for the application, create a new instance of the Activity, call onCreate() passing the saved instance Bundle as a parameter. It will also call onRestoreInstanceState() passing the saved instance Bundle as a parameter.
I have created two activities A and B. In the Activity A, using onSaveInstanceState method I am saving bundle value ex(outState.putString("selectSaveDate", this.CalSelectedDate)) and going to the Activity B. When I hit back button to the Activity A , In the oncreate method the bundle value is null. I am unable to get my saved value in the oncreate method.
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.clear();
Log.i("bundleSave", "tester1" + this.CalSelectedDate);
outState.putString("selectSaveDate", this.CalSelectedDate);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null){
Log.i("todolist", "dsa" + savedInstanceState.getString("selectSaveDate"));
}
}
You only store data in a bundle in the OnSaveInstanceState method to persist data when your activity is destroyed and re-created (such as when rotating the screen or when the android os may decide to kill your activity if it is low on resources). When you launch activity B on top of your currently executing activity A, A is put in to a stopped state (therefore, your A activity is not destroyed). Also, when you come back from onStop, the next method that is called is onStart() (technically onRestart() is called be before onStart() but I find that callback is rarely ever implemented.
In conclusion, if your trying to keep persist data between launching an activity on top of your currently executing activity, you can just store that data in instance variables for that activity. If your trying to persist data between app launches then your going to want to look into storing data in Android's built in sqllite database or Android's SharedPreferences.
You should also obtain a real good understanding of the Activity lifecycle (its tricky but needed to code successfully in android):
http://developer.android.com/training/basics/activity-lifecycle/index.html
please try to Override onSaveInstanceState(Bundle savedInstanceState) and write the application state values you want to change to the Bundle parameter like this:
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
// Save UI state changes to the savedInstanceState.
// This bundle will be passed to onCreate if the process is
// killed and restarted.
savedInstanceState.putDouble("myDouble", 1.9);
savedInstanceState.putInt("MyInt", 1);
savedInstanceState.putString("MyString", "How are you");
// etc.
}
it will get passed in to onCreate and also onRestoreInstanceState where you'd extract the values like this:
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
double myDouble = savedInstanceState.getDouble("myDouble");
int myInt = savedInstanceState.getInt("MyInt");
String myString = savedInstanceState.getString("MyString");
}
or follow activity life cycle for better understanding.
Iam little bit amazed with this.I have an onResume() in my activity.Its called and works well in my emulator, but in a physical device samsung galaxy note for specific with jellybean installed,its not called.Instead onCreate() is called all the time.Why this happens?
public void onResume(){
super.onResume();
if(firsttime){
try {
Toast.makeText(getApplicationContext(), "Resuming Activity",Toast.LENGTH_LONG).show();
addReminder();
} catch(Exception exception) {
exception.printStackTrace();
}
} else {
firsttime=true;
}
}
This is my code.firsttime is a static boolean variable.It is used to prevent onResume() being called when app is started for the first time
Considering your current scenario, you should save variable in preferences instead of relying on activities lifecycle since lifecycle depends on many things.
Using static variable for this scenario is bad choice in general.I think this should solve your problem.
Try to print something inside the onResume and check it in LogCat.... the code inside onResume may be causing this.
or else can you elaborate your question?
I think here is what happens,
when your app not the Top app, the activity manager actually destroy the activity, it only called
public void onSaveInstanceState(Bundle savedInstanceState)
no
onStop
called, so no
noResume
will be called.
The correct to do this is, when put all states of this activity when
public void onSaveInstanceState(Bundle savedInstanceState)
called.
and in your onCreate() function, do such thing
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Always call the superclass first
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore value of members from saved state
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
} else {
// Probably initialize members with default values for a new instance
}
...
}
to check if you have some saved state.
Most code was copy from android developer site:
http://developer.android.com/training/basics/activity-lifecycle/recreating.html
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.