when I start activity with following code.
intent = new Intent(MainActivity.this, New1Activity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult(intent, StaticValue.REQUEST_CODE_MENU_01);
after New1Activity activity showed up, open another package app such as Facebook app and then go back (by multitasking switch or back button) to my app.
In this scenario, I expected New1 activity will be given but MainActivity is shown.
In addition, AndroidManifest.xml is as below.
<activity
android:name="mypackage.MainActivity"
android:screenOrientation="landscape"
android:launchMode="singleTop"
android:noHistory="true"
android:label="#string/app_name"
>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".New1Activity"
android:launchMode="singleTop"
android:noHistory="true"
android:screenOrientation="landscape"
/>
I noted noHistory and singleTop to each activity because of my app performance management.
How can I persist my activity status whenever I go back from other app?
Oh, my stupid.
I removed noHistory="true" and it works. (Let say RTFM. LOL)
below is quoted from android documentation,
android:noHistory
Whether or not the activity should be removed from the activity stack and finished (its finish() method called) when the user navigates away from it and it's no longer visible on screen — "true" if it should be finished, and "false" if not. The default value is "false".
A value of "true" means that the activity will not leave a historical trace. It will not remain in the activity stack for the task, so the user will not be able to return to it.
This attribute was introduced in API Level 3.
Related
I have an app that acts as a Launcher. This app has 3 activities:
SplashActivity: shows a splash screen while loading, then launches LauncherActivity and finishes. This is the Activity marked as launcher in the manifest.
startActivity(Intent(this, LauncherActivity::class.java))
finish()
<activity
android:name=".SplashActivity"
android:label="#string/app_name"
android:screenOrientation="landscape"
android:theme="#style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
LauncherActivity: main activity for Launcher. Has a menu button that launches DashboardActivity.
startActivity(Intent(this#LauncherActivity, DashboardActivity::class.java))
<activity
android:name=".LauncherActivity"
android:launchMode="singleTask"
android:screenOrientation="landscape" />
DashboardActivity: shows a list of apps and launches them through their launch intent.
private val DEFAULT_FLAGS_APP_LAUNCH = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(packageManager.getLaunchIntentForPackage(packageInfo.packageName).apply {
flags = DEFAULT_FLAGS_APP_LAUNCH
})
<activity
android:label="#string/apps"
android:theme="#style/TNA"
android:name=".DashboardActivity"
android:launchMode="singleTask"
android:screenOrientation="landscape" />
All activities are launched through startActivity, including the apps.
I want the standard Android Launcher behavior, that is: when entering an app through DashboardActivity, if I click home button, go to the main Launcher activity (LauncherActivity), and when clicking back, go to the dashboard (DashboardActivity).
The problem I have is that when clicking home, it goes back to DashboardActivity, not to LauncherActivity. If I finish DashboardActivity, then when clicking back on an app, it goes back to LauncherActivity.
Any ideas on how to solve this?
This is definitely back/task stack related. See this link for more information about the task stack.
When you go from LauncherActivity to DashboardActivity, the dashboard is placed on to the task stack. When the LauncherActivity is requested again via the HOME button, the task stack is restored back to the last Activity which was in use after launching the LauncherActivity, which was DashboardActivity.
You have several different options to resolve this:
Don't use a separate Activity for the "dashboard". Consider a drawer or even a Fragment which shows the content and can be popped back to the main LauncherActivity when it is done calling startActivity to launch another app.
After your DashboardActivity calls startActivity, it should call finish() so it will get popped off the current task stack.
Usually launchers are setup to be launched in singleInstance mode, preventing multiple instances of the launcher Activity to run at the same time. Note that you'll need to support onNewIntent in your LauncherActivity.
To prevent odd interactions with the task manager, consider setting FLAG_ACTIVITY_NO_HISTORY when launcher your DashboardActivity.
I have two applications installed on my device, application A and application B.
When a user launches application A, they press a button to launch application B.
I use the following code:
Intent intent = Global.CurrentContext.getPackageManager().getLaunchIntentForPackage("some.random.app");
Global.CurrentContext.startActivity(intent);
The first time the user does this, it works fine and works as expected, however, if the user then launches the phones task manager and swipes away application B. When the user then presses the button in application A. The activity is not created.
I believe this is something to do with the way that the task and the activity are being destroyed by android. My thought process is that when the user swipes to kill application B that the activity is destroyed, but the task remains. Then the second time they press the button in application A, that it's attaching to the old task and then not showing for the user.
Application A's activity manifest for the activity:
<activity
android:name="a.a.a.LogonActivity"
android:label="#string/app_name"
android:noHistory="true"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.Light.NoTitleBar"
android:windowSoftInputMode="stateHidden"/>
Application B's activity manifest for the activity:
<activity
android:name=".activity.HomeActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
When I set android:noHistory="false", it works. I think it is android:noHistory="true" killed applicationA's top activity, makes it doesn't work.
What is happening:
Currently when i click the app icon for the first time i am loading
SplashActivity and then loading ActAtomicGodDetailDesc
Now when i minimize the app -- > then go to home screen -- > then
click on the app icon again ActAtomicGodDetailDesc is displaying
instead of SplashActivity
What i want:
Everytime i want the app to fire SplashActivity when i click the app icon from the home screen
manifest
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".SplashActivity"
android:label="#string/app_name"
android:noHistory="true"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ActAtomicGodDetailDesc"
android:label="#string/app_name"
android:screenOrientation="portrait" >
</activity>
</application>
How to achieve this ? any ideas
Everytime i want the app to fire SplashActivity when i click the app icon from the home screen
I think you require to set android:clearTaskOnLaunch="true" on Splash Activity such that whenever you click on app icon then it will start as root activity.
android:clearTaskOnLaunch http://developer.android.com/guide/topics/manifest/activity-element.html#clear
Whether or not all activities will be removed from the task, except for the root activity, whenever it is re-launched from the home screen — "true" if the task is always stripped down to its root activity, and "false" if not. The default value is "false". This attribute is meaningful only for activities that start a new task (the root activity); it's ignored for all other activities in the task.
When the value is "true", every time users start the task again, they are brought to its root activity regardless of what they were last doing in the task and regardless of whether they used the Back or Home button to leave it. When the value is "false", the task may be cleared of activities in some situations (see the alwaysRetainTaskState attribute), but not always.
Suppose, for example, that someone launches activity P from the home screen, and from there goes to activity Q. The user next presses Home, and then returns to activity P. Normally, the user would see activity Q, since that is what they were last doing in P's task. However, if P set this flag to "true", all of the activities on top of it (Q in this case) were removed when the user pressed Home and the task went to the background. So the user sees only P when returning to the task.
If this attribute and allowTaskReparenting are both "true", any activities that can be re-parented are moved to the task they share an affinity with; the remaining activities are then dropped, as described above.
<activity
android:name=".SplashActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:clearTaskOnLaunch="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
I want to clear the back stack within an Activity but not by startActivity() and using FLAG. e.g. when I launch an application from the application icon then the application main activity starts but there is some thing in the back stack like the launcher activity because when we touch the minimized app tab the launcher is visible . I want to remove the launcher application from the minimized applications.
#SorryForMyEnglish's answer is right. You just cannot to implement it. By using android:noHistory="boolean" attribute, see my concept maps below:
Because of ActivityC and ActivityD (last activities) has a true value, so they cannot back to MainActivity, but they can back to ActivityA and ActivityB. Also, ActivityA and ActivityB can back to MainActivity. And the backstack is completely cleared without using this startActivity(intent) to open your next Activity (so you will need FLAG):
Intent intent = new Intent(CurrentActivity.this, NextActivityToBeOpened.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
After you declared the value in manifest, you just need to call this startActivity(intent) to open the next Activity (no FLAG is needed):
startActivity(new Intent(CurrentActivity.this, NextActivityToBeOpened.class));
Is it very simple, right?
Remember:
Set your last Activity with android:noHistory="true" in manifest.
Another Activity must be set with false value.
Apply this attribute for all of your Activity.
As additional, here is how to use it inside your manifest:
<activity android:name=".MyActivity" android:noHistory="true" />
use android:noHistory="true" attribute in Manifest for your Activity
<activity android:name="StartActivity"
android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
In my application I have three activities:
<activity
android:name="com.example.myapp.SplashScreenActivity"
android:exported="true"
android:launchMode="singleInstance"
android:noHistory="true"
android:screenOrientation="sensorLandscape" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.myapp.MainActivity"
android:exported="false"
android:launchMode="singleInstance"
android:screenOrientation="sensorLandscape" >
</activity>
<activity
android:name="com.example.myapp.ListActivity"
android:exported="false"
android:launchMode="singleTop"
android:screenOrientation="sensorLandscape" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.myapp.MainActivity" />
</activity>
The first one is the LAUNCHER, SplashScreenActivity, which is a splash screen that disappears quite soon and it's not shown in recent activities, it starts MainActivity. In MainActivity users can select a category and ListActivity shows the items belonging to the given category. This is done with the following code:
Intent i = new Intent(getActivity(),ListActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
i.putExtra("category",mCategory);
startActivity(i);
In ListActivity the onResume method checks for the "category" extra and shows data accordingly. Since Activity launchMode is singleTop, I've also overridden the onNewIntent method to set the new Intent of the Activity.
This works properly if the app doesn't go in background: in this case, when I restart MainActivity and select a category, ListActivity resumes the old Activity showing data belonging to the previously chosen category.
How should I fix flags/launchMode in such way that my app doesn't resume ListActivity with the old data loaded?
You should not use the special launch modes. These are rarely required and only in very specific circumstances. Remove all the launchMode specifiers from your manifest. You also don't need to use these flags when launching ListActivity from MainActivity:
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
Your use of singleInstance launch mode is causing you all these problems.
Assuming you would ditch all the launchModes and Flags, then activity lifecycle gives you all the information needed to implement application as you have described - maybe there is somethings you have not added?
Once application goes to background, then ListActivity will be allowed to save its state, even if system will kill your process (lack of memory etc.), then still - launching back your app will first bring back ListActivity with previously saved instance state. So you will not have behaviour as you describe : when I restart MainActivity and select a category, ListActivity resumes the old Activity showing data belonging to the previously chosen category.
Still, if you need to keep to your current design, then you should somehow inform ListActivity of new data changes, question is if ListActivity.onNewIntent is being called at all in the case your describe? Have you tried adding Intent.FLAG_ACTIVITY_SINGLE_TOP : as per this blog entry: http://www.acnenomor.com/1094151p2/bug-onnewintent-not-called-for-singletop-activity-with-intentflagactivitynewtask ?