14

I'm facing a very confusing issue for a very small number of my users. The error occurs when a button is pressed inside a Fragment, that starts another Fragment Activity. Here is the stack trace:

I/20:22:23.901 ActivityManager( 1668)
Start proc com.brandall.nutter for activity com.brandall.nutter/.ActivityHomeFragment: pid=8956 uid=10125 gids={50125, 3003, 3001, 3002, 1015, 1023, 1006, 1028}
I/20:22:23.881 WindowState( 1668)
WIN DEATH: Window{41ed1948 u0 com.brandall.nutter/com.brandall.nutter.ActivityLinkAppsFragment}
W/20:22:23.881 ActivityManager( 1668)
Force removing ActivityRecord{411c4188 u0 com.brandall.nutter/.ActivityLinkAppsFragment}: app died, no saved state
I/20:22:23.881 WindowState( 1668)
WIN DEATH: Window{41b6a178 u0 Toast EXITING}
W/20:22:23.881 InputDispatcher( 1668)
Attempted to unregister already unregistered input channel '41ed1948 com.brandall.nutter/com.brandall.nutter.ActivityLinkAppsFragment (server)'
W/20:22:23.871 ActivityManager( 1668)
Scheduling restart of crashed service com.brandall.nutter/.TTSS in 80000ms
I/20:22:23.871 ActivityManager( 1668)
Process com.brandall.nutter (pid 8907) has died.
I/20:22:23.871 WindowState( 1668)
WIN DEATH: Window{411d4ff0 u0 com.brandall.nutter/com.brandall.nutter.ActivityHomeFragment}
E/20:22:23.871 InputDispatcher( 1668)
channel '41ed1948 com.brandall.nutter/com.brandall.nutter.ActivityLinkAppsFragment (server)' ~ Channel is unrecoverably broken and will be disposed!
W/20:22:23.871 InputDispatcher( 1668)
channel '41ed1948 com.brandall.nutter/com.brandall.nutter.ActivityLinkAppsFragment (server)' ~ Consumer closed input channel or an error occurred.  events=0x9

Due to this line of the error:

com.brandall.nutter/.ActivityLinkAppsFragment}: app died, no saved state

I've been reading many posts about Fragment saved states, but none seem to apply in my circumstances, rather to the Fragments themselves, which aren't mentioned in the stack trace. The other posts suggest adding to each Fragment:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
}

I currently don't override the onCreate method in any of my Fragments.

I've also seen suggested adding this to each Fragment:

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    setUserVisibleHint(true);
}

Apart from the fact that it's only happening to a very small number of users, the most baffling issue is with the Context used:

final Intent sa = new Intent(getActivity(), ActivityLinkAppsFragment.class);
getActivity().startActivity(sa);

My application has a foreground Service and if I instead use the static Context of that (through a static getServiceContext() method) in the Intent above, the problem no longer occurs for the users and the Fragment Activity opens correctly.

I don't understand why the use of another Context should prevent the issue from happening, but I hope with the information I've supplied, it will make sense to someone!

I can supply the FragmentPagerAdapter code I'm using if it proves to be relevant, but it's pretty standard.

I thank you in advance

EDIT - Something very important I forgot to add. This does not cause the app to crash. Instead the Activity from which the Fragment is in, gets restarted immediately.

ANSWER - This was caused due to me calling System.exit(0) under circumstances I thought only possible when the user wanted to 'flush' the memory usage of the app. I was wrong and it could also be called when the user's device was handling low memory conditions. @beworker's answer below is marked as correct, as he noted ActivityManagerService.handleAppDiedLocked() which was a result of this.

brandall
  • 6,094
  • 4
  • 49
  • 103
  • 1
    Does this still happen if you use the recommended pattern of registering a listener in the `Activity` and handling `startActivity` there? `Fragments` should never start there own `Activities` because there's no way for them to know if an Activity should be started, or a Fragment should be added/replaced. Also, why are you using `Intent.FLAG_ACTIVITY_NEW_TASK` here? – Paul Burke Aug 21 '13 at 18:53
  • @PaulBurke The Flag should not be there - Sorry to be misleadinng, it's left in from my testing, I'll remove it from the question. As I handle my Activities as a very simple stack, I've never had to consider whether or not they 'should be started'. I'll search for the listener approach you describe. Thank you. – brandall Aug 21 '13 at 19:04
  • @brandall can you share Fragment's `onClick()` and lifecycle methods? – sergej shafarenka Aug 21 '13 at 19:45
  • @beworker Thanks for wanting to help - I can reduce the code down to just a single button and still replicate. The code would then look almost identical to this example. http://www.javacodegeeks.com/2013/04/android-tutorial-using-the-viewpager.html It's such a tiny number of users this problem occurs for. – brandall Aug 21 '13 at 20:04

1 Answers1

11

I looked through the Android source code for the message in stack trace and found out that it comes from ActivityManagerService.handleAppDiedLocked() method. Descriptions of this method says:

"Main function for removing an existing process from the activity manager as a result of that process going away. Clears out all connections to the process."

This happens when application gets killed. It can be killed by the system, by another application (e.g. a task manager app) or when the application gets finished by itself (e.g. System.exit(0)).

Bruno Bieri
  • 9,724
  • 11
  • 63
  • 92
sergej shafarenka
  • 20,071
  • 7
  • 67
  • 86
  • Interesting - that would explain the very small amount of issues! I'll read up on it now and check with my users! Thanks. – brandall Aug 21 '13 at 19:06
  • I've checked with a few of my users with this issue and they don't have a task killer installed... I was really hoping you were right though! – brandall Aug 21 '13 at 19:29
  • You were right - Not from a user's point of view, but from my implementation in the app. I was calling System.exit(0); under certain circumstances that I thought would never been executed - I was wrong, it happens, I assume, under heavy memory load. It was this answer that linked the two - http://stackoverflow.com/a/14756126/1256219 If you want to update your answer with a reference to that post and how you knew it was ActivityManagerService.handleAppDiedLocked() related, I'll mark it as correct. Thank you! – brandall Aug 22 '13 at 22:18
  • If you want to update your answer with the above, I'll accept it? – brandall Sep 02 '13 at 12:33
  • I updated the message, but I am not sure hot to refer a message you posted in the comment. It is not related to the questions. You didn't mention you used `System.exit(0);`. Otherwise you would immediately said this is the issue. – sergej shafarenka Sep 02 '13 at 17:44
  • Nice explanation, any suggestions on how to locate the problem in code? – Summer Sun Nov 20 '19 at 03:13