Skip to main content

Android lifecycle weirdness with singleTop and foreground service?



Here's the scenario:





  • Start Activity A



  • Activity A starts service S



  • Service S runs in foreground mode and shows up a notification which when pressed takes the user to Activity B (which has launchMode="singleTop")



  • Activity B shows up



  • Press HOME



  • Go into DDMS and kill your application process to simulate that your app died (press red STOP button)



  • Android will say "Rescheduling crashed service in 5000ms" (sometimes longer)



  • Service S restarts and notification is shown.



  • Press the notification icon when the service restarts...







...at this time, Android will recover both Activities A and B due to the fact the process ended unexpectedly. But despite the fact Activity B is singleTop android will spawn it AGAIN because the user clicked on the notification. This results into having A -> B -> B on the activity stack. Pressing back will take you again onto the first recovered instance of Activity B.





Can someone from the Android team clarify what is happening behind the scenes and how to avoid this? What is the best way to simulate that Android killed the process due to low memory? Is pressing STOP from DDMS good enough or an edge case and this should never happen under normal circumstances?





What is the difference between 'Force Stop' from Settings --> Applications versus STOP from DDMS?





Thanks in advance!



Source: Tips4all

Comments

  1. This behavior should not change based on whether or not the process is killed. The activity manager first looks through the server-side stack to decide what to do, and once the stack has been adjusted appropriately it resumes whatever is now at the top of the stack.

    Check your app to make sure it is not calling startActivity() when re-initializing or doing something else like that. Look in the log to see what activities are being started and the intents being used. Use "adb shell dumpsys activity" to see what the current activity stack looks like. Maybe you have cleared the task affinity, so the second activity B is being started in its own task (in which case singleTop would have no impact)?

    Also it is really hard to help people if you don't include useful details about what you are doing. The relevant log statements at the different steps, the state of the activity stack shown by "adb shell dumpsys activity", etc.

    ReplyDelete
  2. I am not too sure about the detailed differences between STOP in DDMS and Force Stop, but I am pretty sure DDMS bypasses some internal Android functionality that Force Stop would perform since I do not remember Android ever reinitializing my activities when i did a Force Stop. If this is true, then I am suspecting that what you are seeing is the result of two different tasks started by Android: one for the old, killed activities and another for when the killed service restarts. You can test this theory by setting the flag to "singleTask" and checking if the same behaviour occurs. Hope this helps.

    ReplyDelete

Post a Comment

Popular posts from this blog

Why is this Javascript much *slower* than its jQuery equivalent?

I have a HTML list of about 500 items and a "filter" box above it. I started by using jQuery to filter the list when I typed a letter (timing code added later): $('#filter').keyup( function() { var jqStart = (new Date).getTime(); var search = $(this).val().toLowerCase(); var $list = $('ul.ablist > li'); $list.each( function() { if ( $(this).text().toLowerCase().indexOf(search) === -1 ) $(this).hide(); else $(this).show(); } ); console.log('Time: ' + ((new Date).getTime() - jqStart)); } ); However, there was a couple of seconds delay after typing each letter (particularly the first letter). So I thought it may be slightly quicker if I used plain Javascript (I read recently that jQuery's each function is particularly slow). Here's my JS equivalent: document.getElementById('filter').addEventListener( 'keyup', function () { var jsStart = (new Date).getTime()...

Is it possible to have IF statement in an Echo statement in PHP

Thanks in advance. I did look at the other questions/answers that were similar and didn't find exactly what I was looking for. I'm trying to do this, am I on the right path? echo " <div id='tabs-".$match."'> <textarea id='".$match."' name='".$match."'>". if ($COLUMN_NAME === $match) { echo $FIELD_WITH_COLUMN_NAME; } else { } ."</textarea> <script type='text/javascript'> CKEDITOR.replace( '".$match."' ); </script> </div>"; I am getting the following error message in the browser: Parse error: syntax error, unexpected T_IF Please let me know if this is the right way to go about nesting an IF statement inside an echo. Thank you.