9

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}
dimsuz
  • 8,969
  • 8
  • 54
  • 88
  • You may be seeing this nasty Android bug: http://stackoverflow.com/a/16447508/769265 To check if that is happening, force close your app and then start it from the HOME screen or list of available applications (do NOT launch it from the installer or via IDE). – David Wasser Feb 23 '15 at 18:05
  • Otherwise, please explain hy you need the alias, maybe there's another way to accomplish what you need. – David Wasser Feb 23 '15 at 18:05
  • @DavidWasser nope, that's not it. No downloads are taking place and it happens on *any* start. I need an activity alias because I accidentaly changed the main activity's name and this leads to removal of an app icon from user's home screen. The company I work for insisted that this needs to be fixed, and having an alias with an old class name is the way I can keep changing main activity name. I guess I'll have to rename it back, because I see no solution to this at the moment. – dimsuz Feb 24 '15 at 12:05

1 Answers1

3

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>
JRaymond
  • 11,625
  • 5
  • 37
  • 40
  • Marking as correct, but I haven't checked if it works and my code changed to much to do that now, let's hope you are right :) Thanks. – dimsuz Apr 30 '15 at 09:59
  • @dimsuz Fair enough :) We found your question because we were having the same problem and this is the workaround I came up with. the explicit classname reference works; the intent filter bit is untested but I assume that it works since it works for `LAUNCHER` – JRaymond May 01 '15 at 16:57
  • I had the same problem, and this solved it. It seems that the alias name rather than the target name is what goes on the back stack. Up-voted. Thank you! – NaxyMatt May 19 '15 at 00:11
  • I dont get how this solves anything, the whole point of those aliases is that you can have multiple different aliases for the same component, so with this solution you are back to one set of intent filters you are using for everything. PS: Android sucks – Nappy Oct 24 '17 at 14:11
  • 1
    @Nappy no, the point of activity aliases is to allow you to refactor an old class that someone added as a launcher shortcut without breaking their experience, or maintain compatibility with some older, exposed API. Sure it would be more convenient if android rewrote the back stack on our behalf, but they don’t. Intent filters are androids preferred solution for component mutiplexing – JRaymond Nov 03 '17 at 14:18