Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having <activity-alias> breaks a contract of singleTop mode

Here's the problem. I have an <activity-alias> in my manifest defined as follows:

<activity
    android:name=".HomeActivity"/>

<activity-alias
    android:name=".MainActivity"
    android:targetActivity=".HomeActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity-alias>

Now, user starts MainActivity using a launcher icon, it forwards to the HomeActivity.

I also have an Intent to start HomeActivity from the navigation drawer. It is started with Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP flags - to reuse existing instance of activity.

The problem is that this does not work as intended and it actually creates a new instance of HomeActivity (even though it is currently on top and visible!). This happens because an activity backstack contains an entry for .MainActivity, not the HomeActivity it forwarded to in the end.

Question: I suspect this might or might not be the bug in Android, but I have a difficult time of figuring out a decent workaround. Asking for help here! :)

I need only single activity started, and when user selects an item in navdrawer, that single activity should get onNewIntent(), not the new activity spawning!

Getting rid of an activity-alias fixes things, but this is not an acceptable option for me...

Here's the adb dumpsys result after the activity is started from launcher and then user selects 'Home' in navdrawer which starts activity directly, not through the alias (this dump confirms that there are two entries with different names):

  Main stack:
    TaskRecord{4181c408 #61 A ru.treto.tile U 0}
    Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=ru.treto.tile/.HomeActivity }
      Hist #2: ActivityRecord{412514b8 ru.treto.tile/.HomeActivity}
        Intent { flg=0x24000000 cmp=ru.treto.tile/.HomeActivity }
        ProcessRecord{412b06e0 10165:ru.treto.tile/u0a63}
      Hist #1: ActivityRecord{41723200 ru.treto.tile/.MainActivity}
        Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=ru.treto.tile/.MainActivity }
        ProcessRecord{412b06e0 10165:ru.treto.tile/u0a63}
like image 927
dimsuz Avatar asked Feb 22 '15 20:02

dimsuz


People also ask

What is activity alias?

description: An alias for an activity, named by the targetActivity attribute. The target must be in the same application as the alias and it must be declared before the alias in the manifest. The alias presents the target activity as an independent entity.

What is exported activity in Android?

The exported attribute is used to define if an activity, service, or receiver in your app is accessible and can be launched from an external application. As a practical example, if you try to share a file you'll see a set of applications available.

What is activity tag android?

activity is the subelement of application and represents an activity that must be defined in the AndroidManifest. xml file. It has many attributes such as label, name, theme, launchMode etc. android:label represents a label i.e. displayed on the screen. android:name represents a name for the activity class.

What is intent Flag_activity_new_task?

The flags you can use to modify the default behavior are: FLAG_ACTIVITY_NEW_TASK. Start the activity in a new task. If a task is already running for the activity you are now starting, that task is brought to the foreground with its last state restored and the activity receives the new intent in onNewIntent() .


1 Answers

Instead of referencing your HomeActivity in the classes that are launching it, you'll need to alter those intents to start "MainActivity" instead.

EX:

Intent intent = new Intent();
intent.setClassName(mContext, "ru.treto.tile.MainActivity");

Alternately, if you're using another IntentFilter scheme, you can move those IntentFilter elements to your alias entry in the manifest:

<activity-alias 
    android:name=".MainActivity"
    android:target="ru.treto.tile.HomeActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <intent-filter>
        <action android:name="ru.treto.tile.ACTION_OF_AWESOME" />
    </intent-filter>
</activity-alias>
like image 115
JRaymond Avatar answered Sep 25 '22 20:09

JRaymond