13

The question title may sounds complicated but here is my situation.

I have a map fragment within an activity. Simple. turn on Storage permission to allow display of Map, works fine. Backgrounds the app by pressing Home button, then turn off the Storage permission and open the app from recent task, app crashes.

The problem is instead of calling onResume() of the host Activity, onCreate() is called on the host Activity as well as onCreateView() of the Map fragment. Thus it is throwing Exceptions.

It seems like the app process is killed when permission is changed and thus Activity is recreated.

    09-24 14:42:55.071: E/AndroidRuntime(12918):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
09-24 14:42:55.071: E/AndroidRuntime(12918): Caused by: 
java.lang.NullPointerException: Attempt to write to field 'int android.support.v4.app.Fragment.mNextAnim' on a null object reference
09-24 14:42:55.071: E/AndroidRuntime(12918):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:718)
09-24 14:42:55.071: E/AndroidRuntime(12918):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1489)
09-24 14:42:55.071: E/AndroidRuntime(12918):    at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:548)

From super.onStart() from the Activity

WenChao
  • 3,586
  • 6
  • 32
  • 46
  • 1
    Lifecycle methods have not been altered. What is happening is the activity was destroyed by the system. This is why your activity is recreated and why onCreate is being called. – eddiecubed Sep 24 '15 at 02:57
  • Are you saying the Activity is destroyed because of Permission changes? Because onResume() is called normally, onCreate() is called instead when permission is changed for that Activity, in my case the map fragment in the Activity. – WenChao Sep 24 '15 at 04:11
  • 2
    When there is a permission change the activity is always destroyed – greywolf82 Sep 25 '15 at 04:54
  • @greywolf82 Yeah. But the thing is the associated Fragment which depends on that permission is still there which crashes the app. – WenChao Sep 25 '15 at 06:44
  • I'm finding this whole discussion hard to believe. Can you please add logging to all the lifecycle methods in your `Activity` so that we can see exactly what happens when the permission is changed? That would be incredibly useful to truly understand this. – David Wasser Sep 29 '15 at 14:39
  • @DavidWasser Hi , I will create a sample app later if have time. But the idea is when you background an Activity that has a MapFragment which depends on Permission. You background this Activity and change the Permission setting and come back to the app from recent tasks tab, the app process is killed but the Activity still tries to recreate the MapFragment thus throw the above exceptions. The temporary solution is to use popBackStackImmediate() in onCreate(). Does this sounds clear to you? Cheers, – WenChao Sep 29 '15 at 23:28

3 Answers3

1

I was having similar issues with the dynamic change in app's permission. After some dig what I understood might be helpful for you also.

Changing permission cause termination of your application by the system and now if you open your app from overview screen, it will restart your application, which is the main reason for your crash because you might be performing an operation on fragment object, which is null now.

An important point here to note is that before termination fragment state is saved in savedinstance object.

To stop crash you should get fragment instance using this line of code -

mapFragment = (MapFragment)getSupportFragmentManager().findFragmentByTag("MAP FRAG");

Here "MAP FRAG" is a tag you have to give to your fragment.

share if you have any confusion.

nikhil bansal
  • 449
  • 5
  • 15
0

The workable solution now is just to call getSupportFragmentManager().popBackStackImmediate(); in onCreate() of the Activity to prevent from trying to recreate the map fragment.

popBackStack() won't work in this case as it is asynchronous.

WenChao
  • 3,586
  • 6
  • 32
  • 46
0

Probably a bit late, still might help out others in the future :)

You should check to see if savedInstanceState is null which is passed to onCreate(Bundle savedInstanceState). If it's null only then, launch the Fragment like so:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_layout_file);

        if (savedInstanceState == null) {
            // do fragment transactions here
        }
    }
Sazid
  • 2,747
  • 1
  • 22
  • 34
  • ok but after onCreate() is called, ondestroy() is also called so that app is closed. Does savedInstanceState prevent to my app from finish? – Orcun Sevsay Dec 30 '15 at 13:59
  • 1
    @MiloRambaldi `savedInstanceState` just contains information regarding the last state of the app (in case it was stopped by the system due to shortage of RAM or in this case toggling of any kind of permissions). It has no means to prevent the app from being killed. – Sazid Dec 31 '15 at 17:11