是否可以在同一个 apk 中集成不同的 parameters/styles/images/code?

Is it possible to integrate different parameters/styles/images/code in the same apk?

我知道这个问题不能自我解释,所以让我详细说明一下。

我有一个应用程序提供给我的客户,现在它们的工作方式相同,只是图标、图像、颜色和一些字符串参数(例如应用程序名称、特定的 link 到网络服务,用于检查更新等的代码

我将它们放在不同的项目中,我在一个项目中进行更改并将这些更改合并到其余项目中,我生成 apk,然后将它们上传到服务器以进行更新。

我认为从长远来看这不是很有效,因为如果我最终让 100、1000 个客户更新某些东西,那将是一个非常漫长而乏味的过程。

除此之外,一些客户可能会要求向应用程序添加特定功能,因此需要牢记这一点。

我想知道是否可以只使用 1 个项目而不牺牲自定义:

我对 android 比较陌生,所以我不知道我是否遗漏了其他选项,所以这就是为什么我要问你什么是最好的以及在哪里学习实施它们,希望你可以帮我。

提前致谢

我想你要找的是口味。 Android 文档中有非常好的文档。参见 https://developer.android.com/studio/build/build-variants.html

考虑到这允许为每个变体定制许多不同的东西:资源、Gradle 脚本中的变量,甚至代码。

适合您情况的最佳解决方案是让您的应用尽可能动态化。你必须把所有的东西都放在服务器上,比如图标、字符串、颜色代码、图像等等。对于每个屏幕,您必须从服务器中提取所有这些内容并显示在您的应用程序中。 您必须创建一个管理面板,或者您可以将数据直接更改到您的数据库中。您必须为每个应用程序创建一个唯一的管理员用户,您将在其中上传数据,应用程序将使用用户 ID 获取数据,这意味着您的应用程序也需要身份验证。

如果我没记错的话,您愿意创建类似于下面给出的 link 中的应用程序的东西:

https://play.google.com/store/apps/details?id=com.xpous.myapps&hl=en

如果是这样的话,那你就需要下一番功夫了。因为那是一个需要建立的巨大帝国。

一种可能的解决方案是将您的项目分成模块。

通过这种方式,您可以将核心功能集中到单个可重用(核心)模块中,然后将其作为依赖项包含在您将为每个客户创建的每个新模块中。

这种方法也可能难以维护,但是对于一些 gradle 任务和良好的分支(使用 CI/CD 管道)这将是我的方法。

有点话题,但这样的事情可以让你继续:

在您的应用 build.gradle 文件中

android {
    compileSdkVersion 25
    buildToolsVersion '25.0.2'

    defaultConfig {
        applicationId 'com.my.app'
        minSdkVersion 16
        targetSdkVersion 25
        versionCode 1003
        versionName '0.1.3'
    }

    signingConfigs {
        release {
            //Dummy
            storeFile file('keystore/debug.keystore')
            keyAlias 'androiddebugkey'
            storePassword 'android'
            keyPassword 'android'
        }

        debug {
            storeFile file('keystore/debug.keystore')
            keyAlias 'androiddebugkey'
            storePassword 'android'
            keyPassword 'android'
        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.release

            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

            buildConfigField "String", "API_URL", '"http://my_api.com/"'

            manifestPlaceholders = [appName: "Awesome App", appNameSuffix: ""]
        }

        debug {
            debuggable true

            buildConfigField "String", "API_URL", "http://my_api_staging.com/"'

            manifestPlaceholders = [appName: "Awesome App", appNameSuffix: ".Development"]
            applicationIdSuffix = ".debug"
            versionNameSuffix " Debug"
        }
    }
}

在清单中

 <application
        android:icon="@mipmap/ic_launcher"
        android:label="${appName}${appNameSuffix}"
        android:theme="@style/AppTheme">

在构建时,您的清单占位符将替换为 gradle 文件中提供的值。

您还可以访问您声明的字段。 例如让 API_URL。

您可以为每个客户指定不同的 api url,然后像这样使用它:

Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(BuildConfig.API_URL)
                    .build();