How to handle android child activity not finishing

Go To StackoverFlow.com

1

I've got an Android app that I want other apps to be able to launch via an intent. This allows other apps to interact with mine and provide initial inputs etc.

The calling App (call it App-A) does the following:

Intent intent = new Intent("com.myapp.dosomething");
intent.putExtra("com.myapp.value1", "1.25");
intent.putExtra("com.myapp.value2", "bob");

startActivity(intent);

My activity is started with the intent filter:

<intent-filter>
<action android:name="com.myapp.dosomething" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>

Everything works fine if the user goes through the normal flow of my app. The user does stuff and then when I know the user is done I call finish() on my activity. Everything is dandy.

However, if part way through doing stuff in my app the user hits the home button instead of finishing the task we end up with a major problem. If they try and restart App-A from the launcher my app pops up instead. The user can never get back to App-A without force killing my app. Even worse, my app is specifically designed to not retain any data between launches and when re-launched in this way it also doesn't get any of the extra data originally passed in so my app has no way to know that this other app is still waiting on mine.

How do I set things up so that App-A doesn't sit there waiting on my app? It should be able to continue running regardless of what my app does. If my app crashes, or doesn't return a value I don't want the calling app to be hung forever.

Any ideas?

Thanks.

2012-04-03 22:51
by user456771
"The user can never get back to App-A without force killing my app" - Why can't they hit the BACK button? It works for me in a similar situation - Squonk 2012-04-03 23:38
Well, as a user if I start app A I don't expect app B to come up, regardless of what the apps were doing the last time I ran them. Also, for various reasons we're currently blocking the back button (this will be changing soon, it was a bad design decision at the start of the project). But regardless, our app shouldn't start when you try and launch app-a in the first place. There must be some mechanism for an activity dealing with a child activity going awol! - user456771 2012-04-03 23:44
OK - I appreciate you want to clean things up but that's how Android works by default. In my case my app displays a list of videos on a user's home PC. If they select a video my app fires up a 3rd party video player app to stream the video. If the user hits HOME and then later start my app again it resumes playing the video with the 3rd party app. In other words, the user's last action with my app was to start a video so why shouldn't that be what they go back to? BTW, it was me who upvoted your question as I'm curious about an answer even though I don't think default behaviour is wrong - Squonk 2012-04-03 23:55
I guess part of the problem is that my app is designed specifically to not hold onto data between runs (I'm dealing with sensitive financial data and I don't want anything lurking in memory when the app isn't active as it adds potential attack vectors) so if the user is brought back to my app in this way my app is incapable of responding because the extra intent data isn't provided in the re-launch - user456771 2012-04-04 17:53


0

On your end: If your app starts up and the requisite data wasn't sent, the scenario you described probably just occured, so immediately finish and indicate an error (assuming your app was called with startActivityForResult, you can send a result code indicating error). You have no context for what was asked of you anymore, the app waiting on yours isn't getting its data anyway, and the user might as well be brought back to the app they were expecting.

On their end: The calling app should add the flag:

    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);

This flag clears the called app from the activity stack, so users arrive in the expected place next time the calling app is restarted.

Basically, you can do your best to handle this situation, but it's the calling app's responsibility to add this flag and handle this scenario appropriately.

2012-04-04 00:38
by Alexander Lucas
Is there anything else the calling app needs to be doing to handle this? I've tried adding the clear when task reset flag and it doesn't appear to make any difference. If my app doesn't call finish() and the calling app is started again the user still gets pushed back into my app - user456771 2012-04-04 17:49
I should note that in my test I'm assuming the user abandoned the task due to phone call or some other interruption not due to bad input so my app isn't finishing with an error or anything. As I mention in another comment, my app isn't able to continue where it left off as it's deliberately designed to purge data between 'runs' for security reasons and on the resume of my app (when clicking on the calling app icon in the launcher) I'm not getting the extra intent data resent so there is no way for me to even know that I'm supposed to be responding to a caller - user456771 2012-04-04 17:59


0

After lots of messing about with this it really seems that the launch flags and the like are of no help what so ever. The only real solution was to track when my app was launched externally and make sure to always close finish when the app is suspended in this case.

By always finishing in onPause I make sure that the calling app always gets a response of some sort. In the case of an interrupted operation I simply pass back a result of 'canceled'.

2012-04-10 16:07
by user456771