Android Startup process and Main Activity - Design Pattern - android

I have the following problem, and I would like to design the implementation to make sure I will not encounter any issues.
At application startup, I need to do one (and only one) server request to keep the phone up to date. Then I enter into the main activity.
My biggest issue is the Back button with Android, which can potentially bring back my stack to the very first activity, ie, the one that does server synchronisation.
I have thought of the following implementation:
I launched the Main activity straight away
In the onCreate() of the Main Activity, I launch the synchronisation process ... with some background logos, progress bar, etc etc...
Upon completion of the synchronisation, i call finish() function on my Activity.
Will I then return the onCreate(), or straight to onResume() of the main Activity?
Does this implementation make sense?

You can continue doing the same but for the first activity where you do the synchronization thing, make it a noHistory Task. http://developer.android.com/guide/topics/manifest/activity-element.html#nohist
Or in your First Activity, after you call startActivity(MainActivity) you can call finish() and by doing which your FirstActivity will be removed from backstack and then MainActivity will remain on top of the stack.
Hope that helps.
UPDATE
I mean to say is, let FirstActivity be your first activity and you start MainActivity from FirstActivity. After you call startActivity() in your FirstActivity, call finish() in the very next statement. This is completely acceptable.

UPDATED
to prevent your first Activity from being viewed again, you just need to add the following line to you Activity declaration
<activity
android:name=".FirstActivity"
android:noHistory="true" />
Using the noHistory tag will remove your Activity without the need to do it your self programmatically

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.

How to prevent stacked activity from showing when app is re-launched?

I have an annoying issue with the activity stack that I haven't found a solution for.
Basically I have an activity that acts as a "starter" activity (the main activity in my manifest, this is started from the launcher etc). It is translucent, set using:
android:theme="#android:style/Theme.Translucent.NoTitleBar"
What it does is check the Intent that is fed to it. If the intent data is empty, it starts a new activity which is the main activity for the app.
If the intent data contains certain commands the starter activity should perform certain tasks and then exit, not even starting the main activity. So this should happen without any UI (except for a popup message when done).
My problem is that if the main activity has been started, if the user uses the home button to leave it, the next time the starter activity is started with a command, the main activity also shows up briefly.
I'm assuming this is because of the activity stack since I'm not restarting the main activity from the starter activity in this case.
I've tried various solutions to no avail. I can't use finish() in the main activity in onPause or onStop since that also exits the activity if the user for example enters the settings activity and that is not wanted behavior. I also tried variations of re-launching the starter activity with
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
but that doesn't seem to work either.
The thing that is weird is that when this unwanted behavior happens, onCreate/onResume/onStart is not called on the main activity. Still it shows! I'm guessing this is because it is stacked and since the startup activity is translucent, the main activity is shown through it.
Enable the android:noHistory attribute on your activity within your manifest:
<activity
...
android:noHistory="true">
...
</activity>
This will set the activity to be removed from the activity stack when it starts the next activity. The user will not be able to return to an activity that has android:noHistory="true".
See:
Activity Attribute: android:noHistory

Finish activity

I have program with login, main activity and other activities.
First step is login activity(A). If login succeed start main activity(B) and call finish for (A).
working with (B) I'm calling some activities and then back to (B).
When decide to exit - I call logout and try to close (B) calling finish.
This logik works in 70% ot time :(
Unfortunately on 30% after calling finish for (B) - activity(A) appears on screen and start logging me.
Who is starting (B) again? I din't see relation between problem and program usage.
Update:
I put hohistory for (B) and start (B) with FLAG_ACTIVITY_CLEAR_TOP.
UPDATE2: Described behaviour is typical when I set screen orientation mode in code. In manifest is set portrait. When start activity I'm setting orientation depending on user config. This produced onCreaste twice. I got managed to handle this properly, but this causes problem as described. If I don't set orientation - one onCreate is called and no problem with finish.
Check the following links, you will get the solution:
Finish parent and current activity in Android
http://developer.android.com/guide/topics/manifest/activity-element.html#clear).You
You can try this when you logout in activity B. The activity displays the home screen.
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
Are you starting your application from an IDE (like eclipse), or from the app installer? If so, you will see this situation if you do the following.
Launch your application from the IDE or after installation from the installer (displays your first activity)
press the HOME key (takes you back to home screen)
launch your application again by selecting it from the list of available applications
This sequence will create 2 copies of your first activity, one on top of the other. When you finish the top one, the one underneath it will be shown.
You say this doesn't happen all the time. If you don't launch the app from the IDE, but just from the list of available applications you won't see this behaviour. Also, if you never press the HOME key and relaunch the app using the list of available applications you won't see this behaviour either.
When you go from activity A to activity B first time you are supposed to clear your stack top. Otherwise activity A stays in the stack below B and when u finish B, activity B is called again.
you should set in manifest file android:noHistory="true" to make your A activity not to stay on android stack.
In case you would like to do it from code in future by using intents Intent.FLAG_ACTIVITY_NO_HISTORY will do the job for you.. Cheers
Using setScreenOrientation made thinks complicated.
It is not enought to set noHistory for activityA and call activityB with FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_NEW_TASK.
When Start app in portrait mode /as declared in manifest/ - It was OK.
But when call setScreenOrientation - have to call finishB 2 times to exit.
/Probably because ot 2 times onCreate for activityB/.
This made thinks to work:
For activityA: android:noHistory="true" and android:launchMode="singleInstance" in manifest.
Start activityB with startActivityForResult and flags FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_NEW_TASK.
In activityA:
1. startActivityForResult(activityB)
2. finishA.
In activityB - when call finish() for B - because of 'singleinstance' system din't start activityA again.
Hope this help.
If anybody know reason which will cause error - please write me.

How can I launch an activity to be on top of all other activities?

I am trying to create an application that defines two activites. The first activity pretty much runs all of the time. The second activity requires the user to authenticate to use the device.
Most of the time this application works fine. However, I am having problems figuring out how to force the second activity to the top of the window stack. The code calls startActivity passing in an intent to start the second activity. The problem is that when another application is running (e.g. a web browser), the second activity is not on top. When the other application exits, the second activity is visible to take input from the user.
Here is the activity definition for the second activity that I want to have always on top when started:
<activity android:name=".Authenticate"
android:launchMode="singleTop"
android:configChanges="orientation|keyboardHidden">
</activity>
It is my understanding that when start activity is called, it will put the new activity on top. Is there something that I am missing? How can I make the authentication activity come to the top when it is started?
Well AFAIK, you cannot force your Activity to stay on top all the time. If some other process (say Web Browser) creates an Activity after you have created yours, then that processes Activity will have focus and not yours.
whenever a new activity starts it is on top of the stack and if another application is running then it will be on the top of the stack and if you want your activity on top of the stack then you should stop other application being launched....Is there something I am missing then let me know..

How to start an activity from a singleInstance activity?

I have a widget which can pop up small dialogs when clicked. These dialogs are displayed by an activity called RemoteActivity in singleInstance launchMode. In one of these dialogs, there is a button to launch the main app MainActivity, which has the standard launchMode.
However, when this button is clicked, and startActivity() called, MainActivity isn't launched, although I can see the corresponding "Starting activity: Intent { ... }" in logcat.
If I set the launchMode of RemoteActivity to standard then MainActivity gets launched, but this isn't what I want, RemoteActivity is merely an extension of the widget, I don't want it to stack with any other activity.
I also tried with FLAG_ACTIVITY_NEW_TASK but it didn't help, and it shouldn't be necessary anyway according to the docs:
A "singleInstance" activity, on the
other hand, permits no other
activities to be part of its task.
It's the only activity in the task. If
it starts another activity, that
activity is assigned to a different
task — as if FLAG_ACTIVITY_NEW_TASK
was in the intent.
How can I launch my main activity?
UPDATE / ERRATA:
The MainActivity is actually launched but only if it isn't already part of a task. If I launch MainActivity normally through the launcher, and press Back to exit, then RemoteActivity does launch MainActivity.
But if, instead of pressing Back, I press Home to leave MainActivity, then RemoteActivity can't launch MainActivity, although the intent appears in logcat.
I'm testing this on Froyo.
Any idea of what's happening?
Maybe the noHistory flag will work for what you are looking for?
I found the problem: this behavior only occurs when calling finish() before startActivity() in RemoteActivity. If I call startActivity() before finish() then it works fine whether MainActivity is already part of an existing task or not.
Go figure...

Categories

Resources