0

Everytime the application go in background, and the RAM start filling out, the application start loosing variables (if im not wrong, this is the normal behavior of Android, it loose the instances of variables)

When I bring back the app from background the application crash, because I loose the MainActivity.

There is a way to relaunch this activity if there is not activity at all? Is an ambiguous question but I found this question but I don't think is the best choice

ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE );

List<ActivityManager.RunningTaskInfo> taskList = mngr.getRunningTasks(10);

if(taskList.get(0).numActivities == 1 &&
   taskList.get(0).topActivity.getClassName().equals(this.getClass().getName())) {
    Log.i(TAG, "This is last activity in the stack");
}

Im loosing the full activity, well I can get the activity

@Override
public void onAttach(Activity activity) {
    LocalNotification.registerReceiver(reloadReceiver, LocalNotification.RELOAD_CARTMG);
    try {
        mListener = (OnFragmentInteractionListener) activity;
        MainActivity ma = (MainActivity)activity; //THIS IS LOOSE
        ma.openMyList = false;
        ma.openMyAddress = false;
        ma.hideSearchButton();
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString() + " must implement OnFragmentInteractionListener");
    }

    super.onAttach(activity);
}

This is the Log inside the app

com.XXXX.mg E/Uncaught Exception detected in thread {}: Unable to start activity ComponentInfo{com.XXXX.mg/com.XXXX.view.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.XXXX.view.MainActivity.showShoppingCartIcon()' on a null object reference
                                                       java.lang.RuntimeException: Unable to start activity ComponentInfo{com.XXXX.mg/com.XXXX.view.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.XXXX.view.MainActivity.showShoppingCartIcon()' on a null object reference
                                                           at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2426)
                                                           at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
                                                           at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
                                                           at android.os.Handler.dispatchMessage(Handler.java:102)
                                                           at android.os.Looper.loop(Looper.java:148)
                                                           at android.app.ActivityThread.main(ActivityThread.java:5443)
                                                           at java.lang.reflect.Method.invoke(Native Method)
                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
                                                        Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.XXXX.view.MainActivity.showShoppingCartIcon()' on a null object reference
                                                           at com.XXXX.view.shoppingCart.ShoppingCartFragment.onDetach(ShoppingCartFragment.java:411)
                                                           at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1202)
                                                           at android.support.v4.app.FragmentManagerImpl.removeFragment(FragmentManager.java:1349)
                                                           at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:915)
                                                           at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1722)
                                                           at android.support.v4.app.FragmentManagerImpl$3.run(FragmentManager.java:593)
                                                           at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
                                                           at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:339)
                                                           at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:602)
                                                           at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1260)
                                                           at android.app.Activity.performStart(Activity.java:6261)
                                                           at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2389)
                                                           at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490) 
                                                           at android.app.ActivityThread.-wrap11(ActivityThread.java) 
                                                           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354) 
                                                           at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                           at android.os.Looper.loop(Looper.java:148) 
                                                           at android.app.ActivityThread.main(ActivityThread.java:5443) 
                                                           at java.lang.reflect.Method.invoke(Native Method) 
                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) 
                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
Dinorah Tovar
  • 488
  • 2
  • 15
  • It looks like you don't need to check if there is no activity at all, just need to store your activity state before it was removed from memory and then restore to that state. Check onSaveInstanceState and onRestoreInstanceState or onCreate here https://developer.android.com/training/basics/activity-lifecycle/recreating.html – pablobu Nov 22 '16 at 18:39
  • But I can do it with a full activity? @pablobu – Dinorah Tovar Nov 22 '16 at 18:47
  • what do you mean by full activity? – pablobu Nov 22 '16 at 18:48
  • I will update my question – Dinorah Tovar Nov 22 '16 at 18:51
  • Well with that update, check out the fragment lifecycle https://developer.android.com/guide/components/fragments.html onAttach executes first than onActivityCreated() so try doing that on OnActivityCreated() – jompi Nov 22 '16 at 19:01
  • This is not a `RAM` issue. You are getting `NullPointerException` on `MainActivity.showShoppingCartIcon()`. – mallaudin Nov 22 '16 at 19:17
  • @DinorahTovar so, did you tried putting your broadcast registration and your try block on onActivityCreated? still crashing? – jompi Nov 22 '16 at 19:53
  • @mallaudin But that's a function and It works when you star the fragment – Dinorah Tovar Nov 22 '16 at 21:29

2 Answers2

2

I'm not sure if your app crashes just because you loose your MainActivity, you should be coding expecting this kind of behaviour, using onSaveInstanceState like @pablobu suggested is the right approach.

Can we see the logs? If you're loosing the state of your instances that's fine, you should save those states and restore them Recreating an Activity is it because of Fragments? you can also save those too, Handling Fragments Tutorial this is a good read.

Please, can you give us your logcat output, that might help a lot for us to see whats really going on.

EDIT

With your Logcat edit, try to take a look to the fragment lifecycle, onAttach executes first than onActivityCreated(), so if your Activity is already destroyed, your onAttach method will not have your activity, you should wait until your Activity is recreated .

Furthermore, you have your

super.onAttach(activity);

at the end of your code block, put it before your code block.

/**
This method was deprecated in API level 23.
Use onAttach(Context) instead.
*/
@Override
public void onAttach(Context context) { 
super.onAttach(context);
MainActivity mainActivity;
if (context instanceof Activity) {
    mainActivity = (MainActivity) context;
    try {
        mListener = (OnFragmentInteractionListener) mainActivity;
        /**
        Since you are getting a reference and accesing attributes you should be careful
        with NullPointerException, check if not null first.
        Or better yet refactor a little your code using an interface to handle this behaviour or use
        the one you already created and just tell the activity what to do.

        */
        /*if(mainActivity != null) {
            ma.openMyList = false;
            ma.openMyAddress = false;
            ma.hideSearchButton();
        }*/

    } catch (ClassCastException e) {
        throw new      ClassCastException(mainActivity.getClass().getSimpleName() + " must implement OnFragmentInteractionListener");
    }
}
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//since your Listener is global use mListener behaviour that I suggested here.
if (mListener != null){
        mListener.openListOfSomething(false);
        mListener.hideSearch();
    }
}
jompi
  • 360
  • 1
  • 4
  • 16
0

You can use the Bundle savedInstatceState, wich is given in OnCreate and similar methods:

private String aVariable;

@Override
public void onCreate (Bundle savedInstantceState) {
   super.onCreate(savedInstanceState);
   // Get the variable from savedInstanceState, if it isn't empty.
   // If it is empty, it could be the first Activity run.
   try { 
      aVariable = savedInstanceState.get("Key");
   } catch (NullPointerException e) {
      aVariable = "Baum";
   }
}

@Override
public void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
    outState.putString(aVariable, "Key");
}

These methods set the Variable "aVariable" to "Baum" on the first run (NullPointerException, because there is no String to "Key"). Later, when the Activity is going to be destroyed, onSaveInstanceState will be called. There you save your variables (aVariable) under a Key ("Key").

TobTobXX
  • 418
  • 4
  • 17