1

I have an app that crashes after the RAM memory is cleared. I cannot use the onSavedInstanceState because of the current implementation. So, does anybody know, how could I just restart the app when the user tries to open it from Recent Apps? I already tried this code in the Main activity which is the base class for all activities:

if (isFirstApplicationStartUp()) {
        Intent i = new Intent(this, Main.class);
        startActivity(i);
    }

isFirstApplicationStartUp() is a boolean set to true from a class which extends Application (in onCreate).

But this implementation does not work as desired as the previous activities get to be called before this code is executed.

halfer
  • 19,824
  • 17
  • 99
  • 186
Laura
  • 2,653
  • 7
  • 37
  • 59
  • does it crashes in a precise line? – MineConsulting SRL Dec 03 '14 at 15:24
  • 1
    why dont you post the stack trace so we know what the error is and fix it that way instead of trying to hack your way around things – tyczj Dec 03 '14 at 15:25
  • do other applications crash as well when you clear the memory? – Sarthak Mittal Dec 03 '14 at 15:25
  • And you really can't implement it that way that it will run without any preferences on it's first start? All other coding would be a workaround. – Wicked161089 Dec 03 '14 at 15:25
  • If the `boolean` variable is set to true in `onCreate()` of your apps's `Application` class, then it will **always be true**. Because that method is **always called** before any of your application's activities are created. – David Wasser Dec 03 '14 at 15:37
  • 1
    I didn't post the stack trace because it is irrelevant. All the objects become null. So the app crashes wherever I am in the app. The variable is not always set to true. I set it to false in code where it is needed. But I want another approach since with the current one I should check each and every object for null. – Laura Dec 04 '14 at 09:15

3 Answers3

4

You probably don't want to have the app restart from the beginning when being launched from the "recent tasks" list, because your app may be perfectly capable of working. What you need to do is you need to remember if your app has been properly "initialized" (whatever that means). If the user returns to your app and the process has been killed and restarted since your app was initialized, you need to detect this condition and then redirect the user back to the first activity of your app.

The best way to do this is to have a base class for all of your activities. In this base class you implement code in onCreate() that checks if your app has been properly initialized or not. If it has not been properly initialized, you should redirect the user back to the first activity. Something like this:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Check if the application has been restarted by AndroidOS after it has killed the process due to inactivity
    //  in this case, we need to redirect to the first activity and dump all other activities in the task stack
    //  to make sure that the application is properly initialized
    if (!isApplicationInitialized() && !(this instanceof FirstActivity)) {
        Intent firstIntent = new Intent(this, FirstActivity.class);

        firstIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // So all other activities will be dumped
        startActivity(firstIntent);

        // We are done, so finish this activity and get out now
        finish();
        return;
    }

    // Now call the activity-specific onCreate()
    doOnCreate(savedInstanceState);

All of your activities need to inherit from this base class and they should NOT override onCreate(). Instead, they should implement the method doOnCreate(), which will be called from the base class' onCreate() (see above).

NOTE: This only works if the root activity (in this example FirstActivity) is never finished until the app quits. This means that you will always have an instance of FirstActivity at the root of your task. This is required so that Intent.FLAG_ACTIVITY_CLEAR_TOP works correctly.

(doo dah)

David Wasser
  • 93,459
  • 16
  • 209
  • 274
  • "All of your activities need to inherit from this base class and they should NOT override onCreate(). Instead, they should implement the method doOnCreate(), which will be called from the base class' onCreate() (see above)." Why can't they override the onCreate of base activity? – WPMed Dec 01 '17 at 09:26
  • Is it because even if I call finish in the base actitvity, the derived activity's onCreate will still go on executing? – WPMed Dec 01 '17 at 10:08
  • 2
    @WPMed If you override `onCreate()` then you'll need to call `super.onCreate()`. If the method in the base class decides that it needs to redirect to the `FirstActivity`, your `onCreate()` will not know that and may do some stupid things. This solution is cleaner. In the case where `onCreate()` redirects to `FirstActivity`, your `doOnCreate()` will never be called. – David Wasser Dec 01 '17 at 11:40
  • 1
    Ok, I understand it now. Yes, it's a very clean design, thank you! – WPMed Dec 01 '17 at 11:59
  • 1
    @DavidWasser Sorry I accidentally downvoted this. If you make an edit I can undo – MSpeed Dec 04 '20 at 09:44
  • @MSpeed Thanks for the comment. I was wondering why this was downvoted. I've edited the answer so maybe you can fix it. – David Wasser Dec 04 '20 at 11:33
  • 1
    Done, and upvoted for the inconvenience! :) haha – MSpeed Dec 04 '20 at 12:27
0

The android OS is responsible for clearing up ram when it needs it. This means it can liberally kill any app when it is not in use. The app itself tries to save the view components of the app but you are responsible for saving any other variables or restoring any images.

Here is a more detailed explanation: http://www.senzumbrellas.com/collection/home.php?sl=en

By default, the system uses the Bundle instance state to save information about each View object in your activity layout (such as the text value entered into an EditText object). So, if your activity instance is destroyed and recreated, the state of the layout is restored to its previous state with no code required by you. However, your activity might have more state information that you'd like to restore, such as member variables that track the user's progress in the activity.


Instead of setting this boolean, Android gives you a way to access any instance information. You should instead override onSaveInstanceState(Bundle savedInstanceState):

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    //save any state variables you want to keep around.
    //this is not rally meant for large memory intensive objects like images

    super.onSaveInstanceState(savedInstanceState);
}

Then in onCreate check savedInstanceState in onCreate:

if(savedInstanceState != null)
{
    //this means that the activity is being restored
}
toidiu
  • 965
  • 2
  • 12
  • 25
-1

use shared variables instead of global variables in the activities. This solved my problem.

Shil
  • 1