Two Activity at top of stack even after launchMode is singleTop - android

I am opening an Activity when a button is pressed. However, if user presses this button twice fast enough my activity launches two times. To prevent that I added launchMode: singleTop in manifest and also added this flag to launching intent.
But still the behaviour is same. I am not looking to prevent double clicking by using handler threads or enabling disabling it. I wish to know why singleTop is not working in this case.
code in Manifest
<activity
android:name=".MyActivity"
android:screenOrientation="portrait"
android:theme="#style/MyTheme"
android:launchMode="singleTop"
android:windowSoftInputMode="adjustResize" />
Intent
val intent = Intent(context, MyActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
activity?.startActivityFromFragment(this, intent, REQUEST_CODE)
Update
Upon more investigation I found that startActivityForResult is not respecting the flag. startActivityFromFragment calls startActivityForResult
I wrote a sample which reproduces this here

You don't need to use signeTop. You can use any delay method on your button so that it won't get clicked immediately next time. If you are using rx android you can use below method. or you can create your own simple logic.
RxView.clicks(view).throttleFirst(500, TimeUnit.MILLISECONDS).subscribe(empty -> {
// action on click
});

Related

Starting a non-Main Activity from other app clearing its top

I have two apps, the app 'A' and app 'B' and the first app it's composed of one activity (1) and the second app have two activities (1, 2).
The thing it's that I need to call from A1 to B2 without having B1 appearing. But when I call it, always shows first the B1 and then passes automatically to B2 and when I push back on B2 I need to get back to A1, but it returns to B1.
This is my code when calling the intent:
val intent = Intent()
intent.component = ComponentName("com.app.appB", "com.app.appB.route.to.activity2")
intent.putExtra("stuff", someStuff)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
And this is the activity2 from B on its manifest:
<activity
android:name=".route.to.activity2"
android:screenOrientation="portrait"
android:exported="true">
</activity>
I've tried to change the flags but whey I do I get this error:
android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
Also I've tried adding noHistory = true to the manifest but doesn't change anything.
I hope someone can help soon, thanks!
EDIT 1
Also tried to use an intent-filter like said in this post: Launch Activity from another Application Android but still not working, the behaviour remains the same.
Added this to the activity in the manifest:
<intent-filter>
<action android:name="com.app.appB.route.to.activity2.LAUNCH_IT"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
and called the activity this way:
val intent = Intent()
intent.action = "com.app.appB.route.to.activity2.LAUNCH_IT"
intent.putExtra("stuff", someStuff)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
applicationContext.startActivity(intent)
After a lot of research and tries, I've found that adding the next parameter to the activity in the manifest works like a charm. I hope this can help someone else:
android:launchMode="singleInstance"

FLAG_ACTIVITY_CLEAR_TASK not work with FLAG_ACTIVITY_REORDER_TO_FRONT

I have a problem with an activity which is started with FLAG_ACTIVITY_REORDER_TO_FRONT is not recreated and present on the screen after FLAG_ACTIVITY_CLEAR_TASK.
So the step is:
Open app, enter Welcome Activity.
Finish Welcome activity and start activity A without specific intent flag.
Start activity B with FLAG_ACTIVITY_REORDER_TO_FRONT from activity A (new instance of B is created and now stack became A->B).
Start activity A from B with FLAG_ACTIVITY_REORDER_TO_FRONT (existing A instance brought to top of stack so stack became B->A).
And under some condition, I need to start over from the beginning (just like another normal app launch), so started Welcome activity using FLAG_ACTIVITY_CLEAR_TASK.
So the app will enter phase 2 again after phase 1, which is what I expected, but then, if I try to start activity B again with FLAG_ACTIVITY_REORDER_TO_FRONT from activity A, there is activity B's callback 'onNewIntent, onStart, onResume' in a row, but it doesn't present on the screen.
It looks like to me that there is still the previous instance of activity B somewhere but not showing to me.
I don't specify launch mode for either activity A or B.
I know that document says about FLAG_ACTIVITY_CLEAR_TASK that "This can only be used in conjunction with FLAG_ACTIVITY_NEW_TASK.". And use them together does solve my problem, but then if I click home button to put app background and then launch again, it will become another app launch (enter phase 1) but not back to the previous top activity.
So my questions are:
When I use FLAG_ACTIVITY_CLEAR_TASK to start welcome activity, I don't see onDestroy of either activity A or B, is it by design?
If they are not destroyed, where do they stay and can I have a reference to them?
How can I make activity B presented on the screen after all of these steps?
Code for phase 5:
Intent i = new Intent(A.this, WelcomeActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
Thanks in advance.
AndroidManifest.xml
<activity
android:name=".activity.WelcomeActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
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=".activity.A_Activity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait"
android:theme="#style/BaiduMapTheme.MainMap"
android:windowSoftInputMode="adjustPan" />
<activity
android:name=".activity.B_Activity"
android:configChanges="locale|fontScale|keyboard|keyboardHidden|layoutDirection|mcc|mnc|navigation|orientation|screenLayout|screenSize|touchscreen|uiMode"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateVisible" />
OK, now I think I have those questions because of my incorrect using of the intent flags.
First of all, I should use FLAG_ACTIVITY_CLEAR_TASK and FLAG_ACTIVITY_NEW_TASK at the same time as the document says.
Then everything looks normal and as expected, except one that: if I put the app into background and then click the launch icon again, the WelcomeActivity will be created again.
Previously I thought my existing activity stack is cleared and a new WelcomeActivity is created, but it turns out the existing activity stack is still there, but an extra WelcomeActivity is created, so what I need to do is add some extra flag in WelcomeActivity to determine if it's created in this condition, if yes, then just call finish() in onCreate(), then I can back to the previous activity I was in before enter background.

StartActivityForResult result in a new item on OverviewScreen

I want to launch an activity from another application inside my own app. I have control over both applications.
For it, I'm using the explicit intent and it works well.
Intent intent = new Intent();
ComponentName componentName = new ComponentName("br.com.example.app","br.com.exemple.app.myactivity");
intent.setComponent(componentName);
My problem occurs when I click on the overview button, the new application appears inside the same item when overview screen (Recents Screen). Thus, the user can figure out if he is one the App1 or App2. Actually, he will think that he is still inside App1.
How do I force it to appear on a different item on the Overview Screen?
I already tried to use
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
and
<activity
android:name=".myactivity"
android:exported="true"
android:screenOrientation="portrait"
android:theme="#style/ApiBaseThemeNoActionBar"
android:documentLaunchMode="always">
</activity>
It seems to work well when using only startActivity(intent).
See the documentation for FLAG_ACTIVITY_NEW_TASK:
This flag can not be used when the caller is requesting a result from the activity being launched.
So in your case, I guess if you're asking for a result, android forces you to stay in the same task.

More than one instance of activity due to intent

For an App I am developing, I override the back button to make it act like the home button so that the state of the main activity is preserved even when the app is exited. Now, I also send a notification to the user from time to time using a service. When this notification is pressed I want to open the main activity again. I noticed though that this creates a second instance of the app, which creates major problems. I am trying to make the main activity go to the front again, without calling oncreate again like so:
Intent to launch main activity again:
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
This doesn't work though. I still end up with two instances of my main activity. Does anybody know how to fix this?
By the way, I already have android:launchMode="singleInstance" in my manifest.
There's a way to force the OS to create only one instance of an activity and thats using the tag launchMode in the Manifest as shown below:
<activity android:name="YourActivity"
android:launchMode="singleInstance"/>
Hope this Helps...
Regards
Try adding this flag to the intent .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP), works for me.

Activity is getting created again instead of resuming and using instance from stack?

I have an android application with several activities .Each and every activity has Application Icon in action bar which helps user to return back to main activity directly instead of pressing back button.My problem is that when I use the icon to start my home activity it does not uses the previous instance from the stack and start creating it again.
My Action bar app icon code is :
startActivity(new Intent(this, DashBoard.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
this above code starts Dashboard activity and calls its both onCreate() and onResume().But If I uses back button to return to this activity from any activity it just calls onResume().
Activity definition from manifest file:
<activity
android:name=".DashBoard"
android:configChanges="keyboardHidden"
android:label="#string/app_name"
android:screenOrientation="portrait" >
</activity>
Why is this happening?Am I missing something to prevent it from not creating it again?Please help
Thanks
Use setFlags(), instead of addFlags(). You are on right track. Use the following code.
Intent intent = new Intent(this, DashBoard.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
Remove the FLAG_ACTIVITY_CLEAR_TOP.

Categories

Resources