<activity-alias>

Unless you've been bit by it before or came across Dan Lew's post, you may have never heard of <activity-alias>. Residing in your AndroidManifest.xml and around since API 1 it represents an alias or symlink to a concrete Activity. One of the best use cases is to prevent launcher icon shortcuts being removed when you change your activities android:name. This is because that identifier is both a file and an externally exposed identifier. When a launcher shortcut is created its linking exactly to that Activity.

Should you refactor that file's name or location you'll break the link. Most commonly the icon just disappears from the users home screen, but is still visible in the All Apps drawer. In other cases the icon remains, but the device says the app is not installed. At best its a minor inconvenience but if you have detailed analytics you might find it negatively impacts usage metrics. Many users just blame it on their phone, but in reality its just one of those hidden side effects of having parts of your app exposed as a public API.

Here is how to fix it:

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

Of course there are a few gotchas that prevent this solution from being rock solid out of the box. Given all the various launchers, both 3rd party and shipped on device, you need to adhere to the following:

  1. <activity> must be declared before the <activity-alias> that intends to use it.
  2. android:name and android:targetActivity cannot be the same.

Once you've done this you'll be happy to know that Android Studio refactoring prevents you from messing up this configuration.