7

How to use the manifest command "replace" to replace an activity from the main package by an activity with the same name but in a flavor package?

com.name.project/main/
-ActivityA

replace by

com.name.project/pro/
-ActivityA
XxGoliathusxX
  • 922
  • 13
  • 34
  • I believe this is a repeated question you should be able to find your result here http://stackoverflow.com/questions/32324213/android-gradle-two-different-launcher-activities-for-two-different-product-flavo – PedroAGSantos Dec 04 '16 at 23:06
  • This works only for the mainactivity – XxGoliathusxX Dec 04 '16 at 23:19
  • Can you explain better whats the purpose? Is the code from activityA same as main ? so why you want to replace? – PedroAGSantos Dec 04 '16 at 23:45
  • Ive got two flavors (free and paid). The Activities in the paid-package extend the default ones in the main(no flavor) and have additionally some licensing implementation that only the paid-flavor needs. – XxGoliathusxX Dec 04 '16 at 23:48
  • 1
    So then I would create a baseActivityA in main and create a ActivityA in free flavor and other in the pro flavor and both extend the BaseActivityA in main – PedroAGSantos Dec 07 '16 at 17:14

1 Answers1

4

You can do this by creating an activity alias for each activity you want to override, and then overriding the alias's target_activity in the flavor's manifest.

  1. Add an alias for your activity to the main manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.company.app">
    <application>

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

    <activity-alias
        android:name="${applicationId}.aliasMain"
        android:targetActivity=".MainActivity"/>

    </application>
</manifest>

It's important to use ${applicationId} when declaring the alias if your flavors have different package names. This is because you launch an activity alias using the built package name.

  1. Change the intents that launch your activity so that they launch it using the alias

    Intent intent = new Intent(); String packageName = context.getPackageName(); ComponentName componentName = new ComponentName(packageName, packageName + ".aliasMain"); intent.setComponent(componentName);

  2. In the flavor's manifest, declare the replacement activity, override the alias's target activity to point at this new activity, and remove the base activity declaration so it will be an error if we try to launch it:

     <application>
    
         <activity
         android:name=".flavor.MainActivity"/>
    
         <activity-alias
             tools:replace="android:targetActivity"
             android:name="${applicationId}.aliasMain"
             android:targetActivity=".flavor.MainActivity"/>
    
         <activity
             tools:node="remove"
             android:name=".MainActivity"
             />
    
     </application>
    

Note that the package name in the manifest tag is the base package name "com.company.app" instead of the flavor's package "com.company.app.flavor". I do this intentionally so I don't have to write out a whole package name anywhere else in the manifest.

Bob Liberatore
  • 860
  • 10
  • 24