使用多模板/风格构建单个 Apk

Build Single Apk with multiable template/flavors

提问人:Hossam Hassan 提问时间:5/7/2019 最后编辑:Hossam Hassan 更新时间:5/19/2019 访问量:394

问:

是否可以构建具有 1 种以上产品口味的 apk?

例如: 我有一个具有 3 种风格的项目(App1 - App2 - App3)。
并且每个应用都有自己的配置,例如 applicationId 等。

现在我想构建不同的模板(不同的 XML 布局),用户应该能够从应用程序内部从布局切换到另一个布局。

我的问题是 res 文件夹会很大,而且很难维护,所以我试图找到一种方法来分离不同的布局并尽可能保持清洁。

如果可以这样做,那么我如何打算或重新启动应用程序以构建其他风格?

我想到的另一件事是在主分辨率中构建所有 XML 文件并选择不同的限定符,就像我们在创建不同的屏幕尺寸(sm - larg - 等)时所做的那样,但我无论如何都找不到添加自定义限定符。

我的代码是这样的:Gradle

flavorDimensions "default"

    productFlavors {

        demo {
            applicationId "test.demo"
            versionCode 2
            versionName "1.1.2"
            resValue "string", "backage_name_file", "test.demo.fileprovider"
            resValue "string", "bc", "com.demo"
            resValue "string", "bc_e", "extra_data.com.demo"
            resValue "string", "default_hostname", "demo.test.com"
            resValue "string", "default_username", "demo"
            resValue "string", "default_password", "demo"
        }
         AppOne {
            applicationId "test.AppOne"
            versionCode 2
            versionName "1.1.2"
            resValue "string", "backage_name_file", "test.AppOne.fileprovider"
            resValue "string", "bc", "com.AppOne"
            resValue "string", "bc_e", "extra_data.com.AppOne "
            resValue "string", "default_hostname", "AppOne.test.com"
            resValue "string", "default_username", "AppOne"
            resValue "string", "default_password", "AppOne"
        }
          AppTwo {
            applicationId "test.AppTwo"
            versionCode 2
            versionName "1.1.2"
            resValue "string", "backage_name_file", "test.AppTwo.fileprovider"
            resValue "string", "bc", "com.AppTwo"
            resValue "string", "bc_e", "extra_data.com.AppTwo"
            resValue "string", "default_hostname", "demoAppTwotest.com"
            resValue "string", "default_username", "AppTwo"
            resValue "string", "default_password", "AppTwo"
        }
}
android android-layout gradle android-gradle-plugin android-productflavors

评论

0赞 theapache64 5/7/2019
恕我直言,如果您只想根据用户输入切换布局,则无需使用产品风格。它可以简单地通过一些陈述来实现。if
0赞 Hossam Hassan 5/7/2019
我已经为多用途 APK 使用了 flavors,我不想使用 if 语句,因为如果我有 50 个 xml 文件并在每次我想制作新模板时复制过去它们,那将太多了
0赞 theapache64 5/7/2019
我认为最好创建一个 if 语句,而不是创建一个模块来切换布局。
0赞 Hossam Hassan 5/7/2019
好的,但是我会遇到一些问题:首先,如果我有 2 个不同的布局 (XML) 文件,第一个将称为 mainactivity.xml,第二个模板将称为 mainactivity2,因为这将导致 java 数据绑定问题。活动方式也是如此。你认为有更好的解决方案吗?
0赞 Hossam Hassan 5/7/2019
我发现这样的东西 stackoverflow.com/questions/28232261/......你可以添加子风格,但你如何在 java 中称呼它?

答:

2赞 Jake Lee 5/8/2019 #1

您不能构建具有多种风格的 APK,就像您不能同时在 debug 和 release buildType 中构建一个 APK 一样。所选风格的配置/资源被拉入实际的 APK 元数据/清单中,因此无法在运行时进行修改。

您需要将所有内容包含在文件夹中,但有几种方法可能有助于使其更易于管理。我推荐前 3 个选项,如果您有大量具有不同行为的代码 + 布局文件,则推荐第 4 个选项:res

  1. 使用 Fragments 可以避免大部分 Java/Kotlin 代码需要重复。
  2. 包括 XML 布局,而不是每次都重新定义所有内容以重用公共元素。
  3. 仔细命名您的文件,例如 .template1_backgroundtemplate2_background
  4. 使用多个模块,每个“模板”一个模块。然后,您将拥有多个合理的文件夹。res

我明白为什么口味似乎是解决方案,但由于您需要在一个应用程序中提供所有口味,因此不幸的是,这种方法行不通。您可能会发现步骤#2将删除几乎所有重复的文件,从而完全避免了这个问题!

评论

0赞 Hossam Hassan 5/8/2019
使用多个模块听起来不错,但我发现的唯一问题是如何在 Java 类中调用它,我的意思是在片段/活动类中,我怎么说 temp == temp_1 show xml from module_1 ,如果我在主 src 中有 java 类或样式,如何在模块内调用它?据我所知,您可以访问内部模块,但模块无法访问外部的内容?
0赞 Jake Lee 5/8/2019
如果你的模块依赖于 等,它可以从它们内部调用任何东西(包括布局/java 类)。因此,该模块将控制适当布局/类中的加载。话虽如此,步骤 1+2 值得首先尝试,因为它们更容易(而且很好)。appmodule1module2app
1赞 Hossam Hassan 5/13/2019
如果没有,我会先尝试找到一个更简单的解决方案,而不是我似乎会选择片段选项
0赞 OmerCohen1994 5/19/2019 #2

您可以使用 sourceSets 命令合并不同风格的资源。 SourceSet 允许您管理 buildVariants 资源文件夹 例如,您可以将 App2 风格配置为包括 App2 res 文件夹和 App1 res 文件夹。 示例代码:

sourceSets {


        App2Debug{
            res.srcDirs = ['src/App1/res', 'src/App2/res']

        }

    }

评论

0赞 Hossam Hassan 5/19/2019
具有不同 XML 名称的多个资源将导致数据绑定问题
0赞 OmerCohen1994 5/19/2019
你说的数据库问题是什么?什么问题?
0赞 Hossam Hassan 5/19/2019
对于数据绑定,您需要在 Java 中按以下方式设置 XML:私有 FragmentHomePageViewBinding 绑定;binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home_page_view, container, false);现在,如果您为同一个 Java 类拥有多个 XML,您将需要将第二个数据绑定重命名为 Binding2 和 Binding 3 依此类推,这意味着当您设置文本视图或布局中的任何内容时,该类中将有太多的双精度
0赞 OmerCohen1994 5/19/2019
我知道。仍然不明白由此引起的问题?它不知道布局?
0赞 Hossam Hassan 5/19/2019
问题是,如果我必须从 API 设置 textview,我将不得不为每个绑定多次执行此操作,这不是最佳选择,您可以想象一个在 UI 中具有大量 id 的类,那么该类可以变得多大