traintrax8 traintrax8 - 4 months ago 33
Java Question

Every intent starts a new task in Android App - how to prevent?

In my application I have several "intents" that I use to transition between different activities in my application. I have noticed a strange behavior that occurs on Samsung devices - but not on Nexus devices - whenever a new intent is created the application launches a second "task" for this new activity! When the user goes to the multi-tasking menu they can see multiple copies of the application! This is not the desired behavior. Any and all advice would be greatly appreciated!

Manifest:

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:launchMode="singleInstance">
<activity
android:name=".MainActivity"
android:screenOrientation="portrait"
android:launchMode="singleInstance">
</activity>
<activity
android:name=".Settings_area"
android:screenOrientation="portrait" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyDieXTCaFoIL0kJ_IM4UMBSQL3sNn92AWM" />

<activity
android:name=".MapsActivity"
android:label="@string/title_activity_maps" />
<activity android:name=".Splash"
android:launchMode="singleInstance">


<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

</activity>
<activity android:name=".aboutPageActivity" />
<activity android:name=".turnOffFromNotification"
android:noHistory="true"></activity>
</application>


I have already attempted removing the launch modes as well as changing the application launch mode to
singleTop
and
standard
.

Intent that creates a second instance:

if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

new Handler().postDelayed(new Runnable(){
@Override
public void run() {
/* Create an Intent that will start the Menu-Activity. */
Intent mainIntent = new Intent(Splash.this,MainActivity.class);
Splash.this.startActivity(mainIntent);
Splash.this.finish();
}
}, splashDisplayLength);
return;
}


Intent that creates a third instance:

public void goToAboutPage()
{
Intent goToAboutPage = new Intent(this, aboutPageActivity.class); //create the intent to go to the map screen
startActivity(goToAboutPage); //actually go to the map screen
}


A third instance can also be created from launching a settings intent:

public void changeToSettingsScreen() //changes the screen to the setting screen
{
readyToSendPackets = false;
sendSwitch.setChecked(false);
// textView.setText("NOT sending"); //set the textview to advise users packets are not being sent
Intent goToSettings = new Intent(this, Settings_area.class);
startActivity(goToSettings);
}


I also over rode the onNewIntent Method:

protected void onNewIntent(Intent intent) {
// super.onNewIntent(intent); //REMOVED THIS TO AVOID DOUBLE INSTANTIATION ON TOUCHWIZ IF ANYTHING BREAKS LOOK HERE FIRST
setIntent(intent); //this allows us to recieve the extras bundled with the intent
// System.out.println("Here is the bindle: " + getIntent().getExtras());
if (getIntent().getExtras() != null) //check to see if there are any extras, there wont be on apps first start
{
Bundle extras = getIntent().getExtras(); //get the extras
String methodName = extras.getString("methodName"); //assign the extras to local variables

if(methodName != null && methodName.equals("turn_send_switch_off"))
{
sendSwitch.setChecked(false);
}
//else if(**other actions that may need to be performed can go here**)
}


Thank you very much for any help!!!

Answer

Usually if you have to force a single instance of the app, you should avoid putting android:launchMode="singleInstance" on each activity seeing as it would try to launch an instance for each activity.

Removing the launchMode from everything except the application should ensure that only the application runs in a single instance, although what @Shaishav said is true, most of the time you can let android deal with the lifecycle of an application by not setting the launchMode, unless you have a real need to ensure only one instance is running at a time.