I have a launcher app which has a singleTask activity as the main entry point. When the user navigates away to another activity or to a 3rd party app and then hits the home button, then this activity should be brought to the front. However what I experience is that for the first home button press only, another instance is created instead (a new task is created, onCreate() is called). In the meantime the old task is still alive, containing the original instance of this activity, but it is impossible to navigate back to that task/activity or to bring it to the foreground.
After the first home button press, the next home button press brings the 2nd instance of this activity to the foreground. Not sure why not the very first instance's onNewIntent() method is called for the first time... So this only happens once, after that always the 2nd instance's onNewIntent() method is called. This means that the original activity will be not accessible..
I tried to bring the task to the foreground, nothing was happening... Like if it never existed (but the task is there with the activity, it is not killed at any point). I can find the task from code and also using a shell script. It contains the original activity
This is happening on Android TV (Os: Pie). Any idea what can be the reason for this? I do not really understand how this is happening... BTW the result is the same if I set the activity to singleInstance.
The activity looks like this:
<activity
android:name=".activities.MainActivity"
android:excludeFromRecents="true"
android:launchMode="singleTask"
android:theme="#style/AppTheme">
<intent-filter android:priority="2">
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.ALL_APPS"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
I tried alternating the above attributes (priority, excludeFromRecents, taskAffinity), also removed them completely, they had no effect...
The home button press sends the following intent:
action: "android.intent.action.MAIN"
category:
"android.intent.category.HOME"
component: the above activity
it has also some extras but I do not think it is relevant
You are experiencing this nasty long-standing Android bug:
Re-launch of Activity on Home button, but...only the first time
You say in a comment that it doesn't happen with real users. That is not actually true. If a real user would install your app from the Play store and then launch it immediately (click the OPEN APP button after installation) then the problem would be reproduced exactly as you describe it.
I was struggling with the exactly same issue for the last couple of hours and I've read many similar Q&A about this topic/bug on StackOverflow. No solution really worked for me until, out of mere curiosity, I did the following.
If you're building a launcher and using onNewIntent() in your MainActivity (although OP doesn't mention that he's using this method), then simply comment out this line:
super.onNewIntent(intent);
Uninstall your app and install it again.
I don't know how this works, but EVEN when you then uncomment the very same line, it still behaves in a proper manner, that is: the app has really only single instance of its main activity all the time. And how I know that? My MainActivity is doing some database operations, and previously I saw in my Logcat that these operations were done twice every time, but now they are done only once.
And BTW my MainActivity tag in AndroidManifest.xml is nothing special:
<activity
android:name=".activities.MainActivity"
android:exported="true"
android:excludeFromRecents="true"
android:launchMode="singleTask">
<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>
Related
My app (a game) has two activities: a launcher activity which shows logo, does initializations and is the main activity of my app, and a client activity which does the 3D rendering and is started by the launcher activity. Thus when the app is running, the back stack is: launcher | client.
What I want with a link is:
if the app has not been started, clicking the link should first start the launcher activity, then the launcher activity start the client activity. Finally the game runs in the client activity.
if the app is running (running in the client activity), clicking the link should switch to and notify the app that the link is clicked (either in launcher or client is ok, better in client), instead of starting another launcher activity.
What I have tried:
I added an intent filter in the declaration of the launcher acitivity:
<activity android:name=".Launcher" android:label="TestApp">
<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.VIEW" />
<data android:scheme="myapp" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
<activity android:name=".Client" android:label="TestApp">
</activity>
And the intent filter works when I click the link: myapp://, the launcher activity is started. But the problem is the launcher activity is started in the browser's task. If I already have an app running, there will be a new instance of my app started in the browers back stack, instead of switching to the already running app.
Then I tried add the attribute android:launchMode="singleTask" into the activity declaration. Then clicking the link will start a new task and the Launcher activity is started in that task. And if the app has already running, the running task is switched to foreground, that's what I expect. But the problem is, the back stack of the app task is changed from "launcher | client" to "launcher", the client activity is gone.
I hope that there is only one instance of my app. Cliking a link should start the app if the app is not running, otherwise switch to the app without affecting the app's current running states.
I searched a lot but don't find a solution, please help me, thanks.
Click here for app links assistant
I want to know what is the differences between the back and up actions.
I've already found online how they work, but I didn't find what different happens when I trigger them.
When I intent another activity and go back with up action, it seems to just show again my last activity without executing any method (my images show like it was cached).
When I intent another activity and go back with back action, it seems to reconstruct the entire layout (my images reloads).
What really happens?
Thanks.
First you must understand the concept of Up and Back navigation, you should read this link about Navigation with UP and Back
When pressed back button the actual screen is removed but when pressed up button relaunch the parent-activity.
In your manifest need to add propert launchMode of activity, something like this
<activity
android:name="com.example.client.app.MainActivity"
android:label="#string/app_name"
android:launchMode="singleInstance"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
I hope you serve.
My app consists of 2 activities:
<activity
android:name="com.domain.android.MainActivity"
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="com.domain.android.AboutActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
I open my app, navigate to second screen, then go to the homescreen. From there I launch the app again - and it starts the main activity. But the app is running, it is just in the background, but why it didn't open the second activity? I guess it is something connected with activity's category. But how to fix that? Thanks.
Welcome to the ever-growing list of developers who have been bitten by this Android bug. Please see Re-launch of Activity on Home button, but...only the first time for all the gory details. And please go to Google Code and star the issues. We need all the noise we can make to get these fixed.
Hold your home button it will show the running apps click on your app it will open the activity from where you left. even if you click on the application launcher it will open the activity from where you left.
your application will not be in the same state sometimes if android needs resources it might end that activity. open an application move to next screen and press the home button and launch again it will open from where you left do the same with 5 or 6 apps then try launching the 1st app it will not be in the same state it will launch from the launch activity but any app you come to home screen and launch immediately it will open from where you left. If the background app is not doing anything android might end it if it needs resource. correct me if i am wrong. additional information i will be happy to know.
One issue may be that you have 2 activities designated as the main activity using:
<action android:name="android.intent.action.MAIN" />
You will probably have two icons in your launcher for your app. Each one will launch a different activity. You might be launching the first one again and again by using the icon for the first activity. Try removing
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
from your AboutActivity activity declaration. This might fix your problem.
I have 2 apps, one of them is calling an activity from the second one through an intent filter like so:
Call in App1 (Parent app)
Intent openApp = new Intent("com.app.intent.Activity2");
startActivity(openApp );
Intent filter in App2 (child app)
<activity
android:name=".app.activity.Activity2"
android:label="#string/app_name"
android:launchMode="singleInstance"
>
<intent-filter>
<action android:name="com.app.intent.Activity2" />
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
At one point the Parent application has to close but the problem is the Activity2 from the second application gets killed as well. I can see that Activity2 is actually running under the same package, is there any way to have the Activity2 persist and run even after the parent applicaiton is closed ?
Thank you
This discussion seems to have what you need. Seems like you need to get the launch intent from the package you want to launch and use that in your intent.
Launch an application from another application on Android
Android will generally run all components from the same APK in a single process, so if one of those crashes the process then they will all be gone.
You can however tell it to put an activity or service in its own process.
<activity
android:name=".app.activity.Activity2"
android:label="#string/app_name"
android:launchMode="singleInstance"
android:process=":my_unique_process">
Of course if your process is dieing unexpectedly, that's a problem that needs to be understood and fixed - this would just be a temporary workaround.
Allow me to explain my predicament.
I have been building an app for a while now where it would immediately enter my MainActivity.class. I had this Activity declared in the AndroidManifest.xml file as such:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
Then I realized that I wanted to add a Login Activity to my app so a NewMainActivity.class was required. I've been able to successfully implement this new Activity. And I changed the <intent-filter> of the old MainActivity.class to the following:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
However this is where my problem arises.
When I press the back key on the Login Page (NewMainActivity.class) it goes through the onPause(), onStop(), and onDestroy() methods. When I start the App again the Login Page (NewMainActivity.class) is not shown, the old MainActivity.class is shown instead.
Can anyone guess what I'm still missing/doing wrong? It seems to me like it should always start on the Login Page everytime now. Let me know if a code sample would help.
Delete from your old MainActivity.class the intent-filter that you've defined:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Update: I've understood your question incorrectly at first. The intent-filter I've proposed to delete does nothing except exporting your activity. This means that any application can call the activity of your MainActivity.class So, in any case it should be deleted.
Now about the login activity. As I understand your scenario is the following. When you start your application it at first starts login activity. Then you enter your credentials and the main activity is appeared if the login process has been successful.
Thus, you have two activities in the stack: login and your main class. When you then push home button and run your application once again it starts from the last activity in the stack i.e. Main activity.
Thus, the problem is not in your intent-filters. You should finish your activities. In this case you'll always start from the login activity.
If at first Yury's suggestion does not work, and you did something similar to what I did, which was copy and pasting your workspace between multiple computers and loading the project to eclipse each time, then simply start a new project and copy the actual text within all your classes to fresh new classes in the new project.