How to force close an app - android

When my app crashes, it loads again in a random activity instead of being force closed.
When I call android.os.Process.killProcess(android.os.Process.myPid()) it follows that behaviour too.
I just want my app to force close if needed and let the user send me their reports.
What should I do to avoid that behaviour?

Are you sure it loads some random activity? Usually it loads the next activity on top of your app's activity stack.
from https://stackoverflow.com/a/7240460/262462:
start first activity (either splash screen, or whatever activity is currently at the bottom of the activity stack) with FLAG_ACTIVITY_CLEAR_TOP (which will quit all the other activities started after it, which means - all of them). Just make to have this activity in the activity stack (not finish it for some reason in advance).
call finish() on this activity

Related

Calling finish() in onPause in child activity so that user refocuses into parent activity. Child activity gets recreated instead

I create a child activity "B" from activity "A". if the user should leave the app for any reason (most likely hitting the home button), I would like activity "B" to end and the app to be at activity "A" once the user resumes.
If I call finish() manually, activity B ends and it returns to activity A. This is the behaviour I would like to happen when the user leaves the app.
I have tried to call finish() in the onPause(), onStop() and in the onUserLeavingHint() of activity B. In each case, this appears to work correctly, and I can see mParent.finishFromChild(this); being called inside activity B.
However, as soon as the user switches back to the app, the onCreate() of activity B gets called and the user ends up in activity B.
How can I ensure I end up in the parent activity when I call finish() from within an onStop() (or similar) handler?
UPDATE: It appears that the issue is related to activity B being declared as using a SingleInstance launch mode. Removing this feature seems to have resolved the issue. Changing this has introduced other issues that I have since managed to fix.
The reason for this happening is that Activity B is set as a SingleInstance Launch Mode. The reason it was set to this (by another developer) is somewhat related to the reason I had wished the activity was ended when the app is in the background - it was to ensure the user could not reach this activity by hitting back on any other activities subsequently dispatched from Activity B.
To resolve this. I first ensured no activities could be created from B. To instead return from B and pass any required Intents on to A. Simplifying the back stack. (Calling activity B with startActivityForResult() is one possible way of doing this.)
Now, the reason SingleInstance causes this issue to arise in this scenario, is because Activity B is launched in a seperate new task. When the user attempts to resume, they re-enter this single-activity task. The rest of the app is running in a seperate task. The only thing the task can reasonably be expected to do is relaunch the activity. When the user presses back, the only thing it can do from there is to close the task (and hence appear to exit the app). For the expected behaviour to occur the user would have had to have selected the other, first task (through a long click of the task list).
Hopefully this self-answer can help someone who has encountered a similar issue.

Android - Is it possible to determine if an activity was started from another task?

This is pretty elaborate, so I'll try and be as clear as possible. Currently, my application needs to reload some data when it is launched. I am loading this data in the onCreate/onRestart methods of my main activity. However, I need to be careful to not reload the data if the user never leaves the current task.
For instance, if I need to start the in-built Contacts application from my main activity to select a contact, then my main activity will pause/stop while I am selecting a new contact. When I return to my main activity, onRestart will be called. In this case, because I have never left the Application's task, I do not want to reload the data. This means some check needs to be included here to determine if the user has come straight back from the Contacts app without ever leaving it.
Otherwise, if the user exits the Contacts app while it was open and re-launched the app from the launcher menu (or recent apps list, etc) - I want to close the Contacts app and reload the data when the Main activity's onRestart method is called.
Is there a way to do this without using any user-frightening permissions (e.g. GET_TASKS). I have been stuck on this problem for a long time now so any help would be GREATLY appreciated :)
Tyvm,
B. Campbell
I learned a lot from the Android docs:
Tasks and Back Stack
Navigation with Back and Up
Application Structure
Here is some highlight:
A task is a collection of activities that users interact with when
performing a certain job. The activities are arranged in a stack (the
"back stack"), in the order in which each activity is opened.
When the current activity starts another, the new activity is pushed
on the top of the stack and takes focus. The previous activity remains
in the stack, but is stopped. When an activity stops, the system
retains the current state of its user interface. When the user presses
the Back button, the current activity is popped from the top of the
stack (the activity is destroyed) and the previous activity resumes
(the previous state of its UI is restored). Activities in the stack
are never rearranged, only pushed and popped from the stack—pushed
onto the stack when started by the current activity and popped off
when the user leaves it using the Back button.
It means when your application pick up a contact, the activity stack in the task might be:
| Activity A in Contacts |
| Activity B in Your App |
| Activity C in other app|
When the user leaves a task by pressing the Home button, the current
activity is stopped and its task goes into the background. The system
retains the state of every activity in the task. If the user later
resumes the task by selecting the launcher icon that began the task,
the task comes to the foreground and resumes the activity at the top
of the stack.
Even if the user exits the Contacts app while it was open and re-launched the app from the launcher menu or recent app list, the activity stack is still like the one we see above. The only possibility that may make your acitity start from another task is another app(might be a launcher app) that start the main activity in a new task by startActivity flags, which is a rare case. In this rare case, you can simply check the uid of the app who start your activity by Binder.getCallinguid() to differentiate it.
EDIT based on comments:
You may check if activity was opened from history by FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY:
if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0){
}else{
}
You can also look into:
android:excludeFromRecents if you don't want your app start from recent apps
android:finishOnTaskLaunch
android:stateNotNeeded
If the data you are loading related to the application life-cycle not to a specific activity, you can load it in application class, so it will not be reloaded again unless your application task is killed.

Android; How can I detect whether a Parent activity is still alive in Activity stack and then receate it

I have activities in sequence as Activity A calling Activity B,When I am on Activity B I press Home button and start another Application (for example Map). If i stay on this second application for a long time say 5-10 minutes and then press Home Button again and choose to Start my application again, then Activity B is started again and works fine. But when i Press Back key - I return to my Activity A again (which is also correct) but it shows a Blank Screen. Ideally in correct version it should show me Acitivty A with the XML data is ListView form.
Alternatively, in the above description, when the other Map Application is started and if the user stay on it only for 1-2 minutes then the above problem doesnt not occur.
Can anyone suggest a solution on the same.
Is it that i need to check in Activity B whether Activity A is still there in Activity Stack (How do i do the same) and If its not in my Activity stack then re-create it.
I tried doing alwaysRetainTaskstate in my Android manifest file for Activity A. But it doesnt work at all
You don't have to do any of that, Android takes care of the technicalities for you - it will recreate your Activity A.
You just need to remember to save A's state when B is opened (take a look at Activity.onSaveInstanceState). When A is restarted, your saved state will be passed to onCreate.
You should really read about Activity Lifecycle
This should help.

android - How to Exit from the application

My Application have 20 activities. Here i want to implement the how to exit from the application when you click on the button(like Logout). it means if you click on the menu button any where of our application then it shows the one button. if click on that then directly comes out from the application. how to implement it.
thanks
Well naresh you can do something like that
first finish the activity from which you are closing application this.finish(); secondly and most impotantly always set a flag i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this clear top when you switch from one activity to another activity and as you know every activity is kept in stack to so this flag remove old activity from top and push new activity in top so around your whole application only one activity is kept in stack
and if this does not work put the whole application in background by avtivityname.moveTaskToBack(); this will move your whole app in back ground but only one drawback when you start your activity it will show your that activity from which you have moved back
System.exit(0);
should work, don't forget Java common functions work on android, there isn't only the android library!
As for the button being in the menu in every activity, you could create a class derived from Activity which creates and handles the menu properly, and make every other activity inherit that derived activity.
First finish the activity from which you are closing application: this.finish();. Secondly and most impotantly always set a flag i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); This clears top when you switch from one activity to another activity. As you know every activity is kept in a stack to so this flag removes old activity from the top and pushes new activity to the top so around your whole application only one activity is kept in the stack.
If this does not work, put the whole application in background with avtivityname.moveTaskToBack();. This will move your whole app to the background. One drawback: when you start your activity it will show your that activity from which you have moved back.

How to finish() every Activity on the stack associated with the Application?

Is there any way to tell Android, "If the user exits this Activity by hitting the 'home' key, immediately finish() every Activity on the stack that has ever been associated with this Application?" Or, alternatively, a way for an Activity whose onPause() method has been forcibly called by a user hitting 'home' to finish() not only itself, but the Activity that started it as well?
The problem I have is workflow. My application's users basically go back and forth between a main Activity and "detail" Activity windows. They see something in the main Activity, tap it, the child detail Activity gets spawned, they use it for a while, then hit back to return to the main Activity. I can't finish() the main Activity after starting the child Activity, because then the back button would quit working. The problem is that now, if the user exits by hitting the home key in a child Activity, it leaves behind a zombie parent Activity. If the user relaunches the application, uses it for a while, then explicitly triggers a shutdown by hitting menu->quit from the main Activity (where I kill the service, then call finish()), the Activity goes away, and the user gets dumped into the zombie Activity from the previous run (which promptly crashes if the user tries to do anything, because the background service it depends on has already been shut down, and all the BroadcastReceivers that would have otherwise been listening have been removed, so its cries for help go unheard).
I'm actually kind of puzzled, because I already have android:launchMode="singleTask" sitting in the manifest tag for my launch activity, and I thought launchMode="singleTask" was explicitly supposed to prevent things like this from happening by making sure that any lingering Activities from a previous run were safely dead before it relaunched.
The easiest way of doing this is:
Intent i =new Intent(CurrentClass.this,HomeClass.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
Perhaps you can mark all the Activities in the stack with clearTaskOnLaunch (see http://developer.android.com/guide/topics/manifest/activity-element.html#clear).You can mark all the Activities that would be in the task with the attribute.

Categories

Resources