是否可以在同一个 apk 中集成不同的 parameters/styles/images/code?
Is it possible to integrate different parameters/styles/images/code in the same apk?
我知道这个问题不能自我解释,所以让我详细说明一下。
我有一个应用程序提供给我的客户,现在它们的工作方式相同,只是图标、图像、颜色和一些字符串参数(例如应用程序名称、特定的 link 到网络服务,用于检查更新等的代码
我将它们放在不同的项目中,我在一个项目中进行更改并将这些更改合并到其余项目中,我生成 apk,然后将它们上传到服务器以进行更新。
我认为从长远来看这不是很有效,因为如果我最终让 100、1000 个客户更新某些东西,那将是一个非常漫长而乏味的过程。
除此之外,一些客户可能会要求向应用程序添加特定功能,因此需要牢记这一点。
我想知道是否可以只使用 1 个项目而不牺牲自定义:
- 我正在考虑在用户第一次打开应用程序并登录时从数据库中检索特定参数,但我认为这对于所有媒体资源(包括自定义图标)来说还不够
- 关于特定功能,我考虑过下载它们并替换默认文件,但我认为这根本不可能
- 所以我考虑将所有脚本保留在代码中,但考虑到大多数用户不会使用这些脚本,这可能不安全并且浪费 space。
我对 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();
我知道这个问题不能自我解释,所以让我详细说明一下。
我有一个应用程序提供给我的客户,现在它们的工作方式相同,只是图标、图像、颜色和一些字符串参数(例如应用程序名称、特定的 link 到网络服务,用于检查更新等的代码
我将它们放在不同的项目中,我在一个项目中进行更改并将这些更改合并到其余项目中,我生成 apk,然后将它们上传到服务器以进行更新。
我认为从长远来看这不是很有效,因为如果我最终让 100、1000 个客户更新某些东西,那将是一个非常漫长而乏味的过程。
除此之外,一些客户可能会要求向应用程序添加特定功能,因此需要牢记这一点。
我想知道是否可以只使用 1 个项目而不牺牲自定义:
- 我正在考虑在用户第一次打开应用程序并登录时从数据库中检索特定参数,但我认为这对于所有媒体资源(包括自定义图标)来说还不够
- 关于特定功能,我考虑过下载它们并替换默认文件,但我认为这根本不可能
- 所以我考虑将所有脚本保留在代码中,但考虑到大多数用户不会使用这些脚本,这可能不安全并且浪费 space。
我对 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();