Preserve Your Launchers: Use Activity Aliases

When you deploy your Android app, the launcher Activity's manifest entry should be treated as a contract. While it is possible to change the launcher after install doing so will confuse apps that previously used the contract. The classic example is putting a launcher on your home screen only to have it disappear after an app update. I'm getting a bit annoyed at how often this problem arises because it's perfectly avoidable!

I assume the reason this happens is because developers want to improve their code's organization (by changing package/class names) which is a noble goal. That said, it is entirely possible to reorganize without changing your launcher's manifest contract, thus preserving users' home screens.

The solution is using <activity-alias> in AndroidManifest.xml. It acts a lot like <activity>, except instead of launching an Activity it lets you route an Intent aimed at one android:name towards another.

Suppose this is what's currently in my manifest:

<activity android:name=".Launcher" >
  <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
  </intent-filter>
</activity>

Here I move and rename my Activity but still preserve the old launcher contract:

<activity-alias
  android:name=".Launcher"
  android:targetActivity=".ui.MyNewLauncher" >
    <intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity-alias>

<activity android:name=".ui.MyNewLauncher" />

What's key here is that the aliased name doesn't even have to exist - I could safely delete my old Launcher class and keep my code pretty. So go forth and stop removing launchers from my home screen!