IllegalArgumentException: setTaskFromReuseOrCreateNewTask - android

I have the next crash when I try to launch an Activity:
2019-10-24 15:12:29.887 4245-4296/fr.zapotec.eliodroid.tv E/AndroidRuntime: FATAL EXCEPTION: Thread-6
Process: fr.zapotec.eliodroid.tv, PID: 4245
java.lang.IllegalArgumentException: setTaskFromReuseOrCreateNewTask: task=TaskRecord{6e69142 #1643 A=fr.zapotec.eliodroid.tv U=0 StackId=1 sz=3} is in a different stack (1) than the parent of r=ActivityRecord{8062424 u0 fr.zapotec.eliodroid.tv/fr.zapotec.eliodroid.SplashActivity t1644} (0)
at android.os.Parcel.readException(Parcel.java:1955)
at android.os.Parcel.readException(Parcel.java:1897)
at android.app.IActivityManager$Stub$Proxy.startActivities(IActivityManager.java:6812)
at android.app.Instrumentation.execStartActivitiesAsUser(Instrumentation.java:1677)
at android.app.Instrumentation.execStartActivities(Instrumentation.java:1632)
at android.app.ContextImpl.startActivities(ContextImpl.java:910)
at android.app.ContextImpl.startActivities(ContextImpl.java:884)
at android.content.ContextWrapper.startActivities(ContextWrapper.java:399)
at fr.zapotec.eliodroid.utils.LaunchActivityUtils.launchTVLastProgram(LaunchActivityUtils.java:22)
at fr.zapotec.eliodroid.standby.StandbyManager.launchAction(StandbyManager.java:253)
at fr.zapotec.eliodroid.standby.StandbyManager.onEventReceived(StandbyManager.java:141)
at fr.zapotec.eliodroid.handset.HandsetEventDispatcherImpl.handleKeyPress(HandsetEventDispatcherImpl.java:229)
at fr.zapotec.eliodroid.handset.HandsetEventDispatcherImpl.handleKeyPress(HandsetEventDispatcherImpl.java:204)
at fr.zapotec.eliodroid.handset.HandsetEventDispatcherImpl.onMessageReceived(HandsetEventDispatcherImpl.java:165)
at fr.zapotec.handsetbluetooth.HandsetManagerImpl.dispatchMessage(HandsetManagerImpl.java:49)
at fr.zapotec.handsetbluetooth.MessageManager.onNewMessageReceived(MessageManager.java:119)
at fr.zapotec.handsetbluetooth.HandsetThread.listenAndWrite(HandsetThread.java:126)
at fr.zapotec.handsetbluetooth.HandsetThread.run(HandsetThread.java:56)
This is the Manifest file:
<activity
android:launchMode="singleTask"
android:name=".SplashActivity"
android:noHistory="true"
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" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
<activity
android:launchMode="singleTask"
android:noHistory="true"
android:name=".StandbyActivity"/>
<activity
android:launchMode="singleTask"
android:name=".main.SimpleMainActivity"/>
<activity
android:launchMode="singleTask"
android:name=".main.InstallActivity"/>
I need the Activity 'SimpleMainActivity' to be one only instance (that's why the 'singleTask')
This Activity can be launched due to Bluetooth events (triggered by a bluetooth device) or due to a given timing in a very specific situation.
The method which launches the Activity is:
startActivity(new Intent(context, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK));
I have the crash when trying to launch the Activity from the 2 different sources almost at the same time.
Anyone knows how to solve this problem without removing the 'singleTask' from my Activity?
For information, my application is the "Default launcher", so "SplashActivity" maybe be launched if system needs to show the launcher. The SplashActivity only shows a splash screen and launches the first activity (SimpleMainActivity.class)

What will likely work is to use a launchMode of singleTop instead and set the flags FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_CLEAR_TOP. The docs do recommend this for activities launched by notifications.

Related

Clearing task from a different stack

I have activity 1 (SplashActivity) running in foreground.
This splash activity is starting another Activity2 in its onStart() callback.
From elswhere (a singleton running in application context) I want to start Activity3 and to clear the task to make it the new root. This call is done several milliseconds after the other startActivity in onStart() and it fails with this exception:
java.lang.IllegalArgumentException: setTaskFromReuseOrCreateNewTask: task=TaskRecord{df9fb2e #10 A=com.example.myapp.myflavor U=0 StackId=1 sz=0} is in a different stack (1) than the parent of r=ActivityRecord{3b14930 u0 com.example.myapp.myflavor/com.example.myapp.SplashActivity t11} (0)
at com.android.server.am.ActivityRecord.reparent(ActivityRecord.java:971)
at com.android.server.am.ActivityStarter.addOrReparentStartingActivity(ActivityStarter.java:1992)
at com.android.server.am.ActivityStarter.setTaskFromReuseOrCreateNewTask(ActivityStarter.java:1808)
at com.android.server.am.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1187)
at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:1002)
at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:567)
at com.android.server.am.ActivityStarter.startActivityLocked(ActivityStarter.java:272)
at com.android.server.am.ActivityStarter.startActivityMayWait(ActivityStarter.java:824)
at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:4497)
at com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:4464)
at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:121)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2935)
at android.os.Binder.execTransact(Binder.java:674)
Activities are defined in AndroidManifest.xml in that way:
<activity
android:launchMode="singleTask"
android:name=".SplashActivity"
android:noHistory="true"
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" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
<activity
android:launchMode="singleTask"
android:name=".Activity2"/>
<activity
android:launchMode="singleTask"
android:name=".Activity3"
android:noHistory="true"/>
Activity2 and Activity3 are started with flag:
Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK
When the first startActivity is called, the only one task has id 14, and it contains only one activity: the SplashActivity.
When the second startActivity is called, the only one task has id -1 and it contains 0 activities.
So, what would be the solution to have the startActivity robust to the situation where another startActivity is in progress ?
Any idea ?
From what I understand, I would avoid this error by removing the singleTask launchmode, but I need it because my application can be started in different ways...
Other point: The exception is thrown when the application is updated from ADB. When the application is automatically starting at the device start, the exception is not thrown. (My application is the default launcher, so it automatically starts). --> That can probably be explained by a different sequence in the start of the two activities.

Android: Recents starts incorrect activity

I am developing an android app which has 2 methodes of starting.
One is the normal way by pressing the app icon on the phone.
The other method is with a deep link from a website.
The deeplink also sends some data which the app needs to do some "stuff". However this should only be done once.
When the deeplink activity is finished it start the main activity. However when I press back (on the device) and open the app from recents it opens the deeplink activity again.
I could exclude the deeplink activity from the recents in the manifest. This also excludes the mainactivity from the recent apps, this should not be the case.
How do I prevent the deeplink activity from beeing started from the recent apps?
My Manifest:
<activity
android:name="MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:launchMode="singleTask"
android:theme="#style/AppTheme">
</activity>
<activity
android:name="DeeplinkActivity"
android:label="#string/app_name"
android:noHistory="true"
android:screenOrientation="portrait"
android:launchMode="singleTask"
android:theme="#style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="app_name" android:host="test" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:host="test" android:path="/" android:scheme="app_name" />
</intent-filter>
</activity>
To switch to the MainActivity I do the following:
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
EDIT:
This post was marked as duplicate with: Android: Starting app from 'recent applications' starts it with the last set of extras used in an intent
However that post is regarding the same activity. I want to change the root activity so when I start the app from recents it does not start the DeeplinkActivity. Yes as a workaround I could check the Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY flag. But then every time the user starts the app from recents the DeeplinkActivity is opened whilst it is not needed anymore.
Setting and or clearing aditional intent values does not seem to work.
I use information from the getIntent().getData()
If you still feel as if this is a duplicate please explain.
Your problem is that both DeepLinkActivity and MainActivity are in the same task, so when the user selects the app from the list of recent tasks, Android will either bring an existing task to the foreground, or if there is no existing task (with live/active activities in it), start the Activity that was the root Activity in the most recent task. You can't predict which Activity will be the root Activity, since the task could be started with either DeepLinkActivity or MainActivity, depending on which one the user chose first.
You really need to have 2 separate tasks to do this. One task will have your DeepLinkActivity in it, and this task should be excluded from the "recent task list". The other task will have your MainActivity in it.
I assume that MainActivity has the <intent-filter> with ACTION=MAIN and CATEGORY=LAUNCHER, even though your posted manifest does not show this.
Your manifest should look like this:
<activity
android:name="MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="DeeplinkActivity"
android:label="#string/app_name"
android:noHistory="true"
android:screenOrientation="portrait"
android:taskAffinity=""
android:excludeFromRecents="true"
android:theme="#style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="app_name" android:host="test" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:host="test" android:path="/" android:scheme="app_name" />
</intent-filter>
</activity>
You definitely do not need launchMode="singleTask" for MainActivity and you probably don't need it for DeepLinkActivity either (that depends on what else you do with this).
Specifying taskAffinity="" ensures that DeepLinkActivity is not launched into the same task as MainActivity, and allows you to launch MainActivity from DeepLinkActivity in a separate task. NOTE: Without specifying taskAffinity, both activities will end up in the same task, even though you specify launchMode="singleTask" for both of them.
Specifying excludeFromRecents="true" on DeepLinkActivity tells Android that the task with DeepLinkActivity as its root activity should not appear in the list of recent tasks.
When you launch MainActivity from DeepLinkActivity, you should do this:
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
and make sure that you call finish() on DeepLinkActivity.
If necessary you can also add noHistory="true" to DeepLinkActivity, but I don't think it is necessary. If the user is in DeepLinkActivity and gets an incoming phone call, after the phone call is ended, DeepLinkActivity should be displayed. If you specify noHistory="true", DeepLinkActivity would be finished immediately when the user accepts the incoming phone call.
Let me know if this is clear and works for you.

singleTask activity not loading properly

I have an activity 'A' defined in Manifest like below:
<activity
android:name=".A"
android:launchMode="singleTask"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
When I launch my APP, that activity is always loaded from the start. It wont start from my prev activity.
When I remove android:launchMode, then it works as I expect.
Since you set android:launchMode="singleTask", the activity A will always be the root of your activities.
From DOCS:
In contrast, "singleTask" and "singleInstance" activities can only begin a task. They are always at the root of the activity stack. Moreover, the device can hold only one instance of the activity at a time — only one such task.
Default mode is standard. So, when you remove android:launchMode="singleTask", your APP returns to standard launch mode.
That's why if you app is always starting Activity A.
If you would like to start a different Activity on launch replace that in the xml name attribute that contains LAUNCHER
<activity
android:name=".ActivityB"
android:launchMode="singleTask"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Where Activity B is an alternate activity.

When using taskAffinity to have multiple Activities in the Launcher for the same app, if one is active the other needs to be clicked twice

Scenario:
Two Activities being shown in launcher for one app, they have different taskAffinities because I was getting the problem of when I open one, hit home, open the other, the first one would be opened. So, I added taskAffinity in the AndroidManifest for the proper tasks.
The problem I'm getting is that if I open one, hit home, hit the second one, it will open the proper task/Activity, BUT I have to click on the icon twice in order for it to open and get, this ONLY happens with the activity that specifies a taskAffinity, the other one opens just fine on the first click every time.
731-1337/? W/InputMethodManagerService﹕ Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy#4e640b6 attribute=null, token = android.os.BinderProxy#3edac0ca
Here is the manifest
<activity
android:name=".firstActivity"
android:theme="#android:style/Theme.Holo.Light.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".secondActivity"
android:label="#string/second_activity"
android:icon="#drawable/ic_second_activity"
android:taskAffinity="secondTask"
android:theme="#android:style/Theme.Holo.Light.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".thirdActivity"
android:label="#string/second_activity"
android:taskAffinity="secondTask"
android:theme="#android:style/Theme.Holo.Light.NoActionBar"/>
I fixed this by adding this to the thirdActivty which was being called by secondActivity immediately on launch.
android:launchMode="singleTask"
So it ended up looking like
<activity android:name=".thirdActivity"
android:label="#string/second_activity"
android:taskAffinity="secondTask"
android:launchMode="singleTask"
android:theme="#android:style/Theme.Holo.Light.NoActionBar"/>
Hope someone finds this solution helpful.

Intent filter works only once

I have an activity called "MainActivity", this is my main activity which declared in the manifest file as launcher:
<activity
android:name="com.example.tester.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VOICE_COMMAND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
The VOICE_COMMAND works only one time and then nothing is happen.
I have tried to separate it into 2 activities: 1 activity is the main and the other is associated with the VOICE_COMMAND intent filter, and still, the application works only once.
If it's separated into 2 activities it works fine only when the application starts immediately from the launcher, but if the application starts from the second activity (with the VOICE_COMMAND intent filter) it works only once.
Any suggestion?
Thank you
I have found the answer:
Setting the attribute:
android:launchMode="singleTask"
and it works fine.
Thank you

Categories

Resources