需求如下:
项目 测试demo 有多个渠道,部分渠道包含支付功能,在主测试代码外,需要一个单独 Activity 调用测试代码。
MainActivity | PayActivity | |
渠道A | 包含 | 不包含 |
渠道B | 包含 | 包含 |
因为支付功能需要引入对应的 moudule,因此希望是测试渠道A时,仅包含MainAcitivity 的代码。测试渠道B时,包含 MainAcitivity + PayActivity 的代码。
代码引入简单,添加 java 路径即可。
qudaob{
// 加入支付相关代码
sourceSets."$name".java.srcDirs += "src/main/code/pay/java"
sourceSets."$name".res.srcDirs += "src/main/code/pay/res"
}
问题是 PayActivity 的注册。如果直接在 AndroidManifest.xml 中注册,那么不包含 PayActivity 时会报错。如果不注册,那么包含 PayActivity 时无法跳转。
前期考虑在 quandaob 文件夹下添加一个AndroidManifest.xml ,让两个 Mainifest 合并,但是一直合并不了,只能另辟蹊径。
使用 manifestPlaceholders
你可以在 build.gradle
文件中为你的 Activity 添加 manifest placeholders,然后在 AndroidManifest.xml
中引用它们。
修改 build.gradle
在 zebra
block 中添加如下代码:
android {
...
defaultConfig {
...
manifestPlaceholders = [
payActivity: "com.xxx.test_playcontrol.PayActivity" // 替换为你的 Activity 完整包名
]
}
}
更新 AndroidManifest.xml
在 AndroidManifest.xml
中,你可以使用占位符来声明 Activity:
<activity android:name="${payActivity}">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
这样在 Manifest中虽然会报红,但是编译是没问题的。Manifest 中会一直包含PayActivity. 这样无论是否有 PayActivity 都可以正常使用了
动态引用 PayActivity
try {
Class<?> dynamicClass = Class.forName("com.xxx.test_playcontrol.PayActivity");
Intent intent = new Intent(this, dynamicClass);
startActivity(intent);
} catch (ClassNotFoundException e) {
e.printStackTrace();
ToastTools.quickToast(mContext, "pay Failed!");
DemoLog.e("功能未启用");
}