如何定义 gluon 应用程序版本
How to define gluon application version
我想把应用程序版本放到我的胶子应用程序中。但我不知道该怎么做。我需要为此创建服务吗?
有一个非常简单的方法,不需要服务,但它可能会导致错误:
您可以在 AndroidManifest:
中为 Android 维护版本号 code/version
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.package"
android:versionCode="1.1.0"
android:versionName="1.1.0">
在 iOS 上相同,在 Default-Info.plist 中:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>your.bundle.identifier</string>
<key>CFBundleVersion</key>
<string>1.1.0</string>
最后,您可以在代码中保留一个静态字段:
public static final String VERSION_NAME = "1.1.0";
例如,您可以从 NavigationDrawer
访问。
但是,每次发布新版本时都需要手动更新。
为避免错误,您可以设置一些 CI 作业来为您完成。例如,请参阅此 commit,它是移动应用程序发布工作的一部分。
魅力羽绒服
但是,避免发布的版本与代码中的变量不匹配的更明确的方法是添加直接读取这些版本的服务。
像这样:
VersionService.java
package com.gluonhq.charm.down.plugins;
public interface VersionService {
String getVersionName();
}
VersionServiceFactory.java
package com.gluonhq.charm.down.plugins;
import com.gluonhq.charm.down.DefaultServiceFactory;
public class VersionServiceFactory extends DefaultServiceFactory<VersionService> {
public VersionServiceFactory() {
super(VersionService.class);
}
}
Android 包,在 src/android/java
:
下
AndroidVersionService.java
package com.gluonhq.charm.down.plugins.android;
import android.content.pm.PackageManager;
import com.gluonhq.charm.down.plugins.VersionService;
import javafxports.android.FXActivity;
public class AndroidVersionService implements VersionService {
@Override
public String getVersionName() {
try {
return FXActivity.getInstance().getPackageManager()
.getPackageInfo(FXActivity.getInstance().getPackageName(), 0)
.versionName;
} catch (PackageManager.NameNotFoundException ex) { }
return "";
}
}
IOS 包,在 src/ios/java
:
下
IOSVersionService.java
package com.gluonhq.charm.down.plugins.ios;
import com.gluonhq.charm.down.plugins.VersionService;
public class IOSVersionService implements VersionService {
static {
System.loadLibrary("Version");
}
@Override
public String getVersionName() {
return getNativeVersion();
}
private static native String getNativeVersion();
}
在src/ios/native
下:
Version.m
#import <UIKit/UIKit.h>
#include "jni.h"
JNIEXPORT jint JNICALL
JNI_OnLoad_Version(JavaVM *vm, void *reserved)
{
#ifdef JNI_VERSION_1_8
//min. returned JNI_VERSION required by JDK8 for builtin libraries
JNIEnv *env;
if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_8) != JNI_OK) {
return JNI_VERSION_1_4;
}
return JNI_VERSION_1_8;
#else
return JNI_VERSION_1_4;
#endif
}
JNIEXPORT jstring JNICALL Java_com_gluonhq_charm_down_plugins_ios_IOSVersionService_getNativeVersion
(JNIEnv *env, jclass jClass)
{
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
return (*env)->NewStringUTF(env, [version cStringUsingEncoding:NSASCIIStringEncoding]);
}
在根级别构建文件:
ios-build.gradle
if (System.getProperty('os.name').toLowerCase().contains("mac")) {
new ByteArrayOutputStream().withStream { os ->
exec {
args '-version', '-sdk', 'iphoneos', 'SDKVersion'
executable 'xcodebuild'
standardOutput = os
}
ext.IOS_VERSION = os.toString().trim()
}
} else {
ext.IOS_VERSION = ""
}
ext.IS_DEBUG_NATIVE = Boolean.parseBoolean(System.getProperty("IS_DEBUG_NATIVE", "false"))
def sdkPath(String platform) {
return "/Applications/Xcode.app/Contents/Developer/Platforms/${platform}.platform/Developer/SDKs/${platform}${IOS_VERSION}.sdk";
}
ext.xcodebuildIOS = {buildDir, projectDir, name ->
if (!file(sdkPath('iPhoneOS')).exists()) {
println "Skipping xcodebuild"
return
}
// define statics do being able to configure the input/output files on the task
// for faster builds if nothing changed
def buildSystems = ["iPhoneOS+arm64",
"iPhoneOS+armv7",
"iPhoneSimulator+i386",
"iPhoneSimulator+x86_64"]
def linkerOutputs = []
def lipoOutput = "$buildDir/native/lib${name}.a"
def nativeSources = ["$projectDir/src/ios/native/${name}.m"]
// the actual task action
buildSystems.each { buildSystem ->
def (platform, arch) = buildSystem.tokenize("+");
def compileOutput = "$buildDir/native/$arch"
def compileOutputs = ["$buildDir/native/$arch/${name}.o"]
def linkerOutput = "$buildDir/native/$arch/lib${name}.a"
new File(compileOutput).mkdirs();
def clangArgs = [
"-x", "objective-c",
"-miphoneos-version-min=6.0",
"-fmessage-length=0",
"-std=c99",
"-fno-common",
"-Wall",
"-fno-strict-aliasing",
"-fwrapv",
"-fpascal-strings",
"-fobjc-abi-version=2",
"-fobjc-legacy-dispatch",
"-I" + System.getenv("JAVA_HOME") + "/include",
"-I" + System.getenv("JAVA_HOME") + "/include/darwin",
"-c",
IS_DEBUG_NATIVE ? ["-O0", "-DDEBUG", "-g"] : ["-O3", "-DNDEBUG"],
"-arch", arch,
"-isysroot",
sdkPath(platform),
nativeSources].flatten()
// "-o", compileOutput,
def linkerArgs = [
"-static",
"-framework", "Foundation",
"-framework", "CoreGraphics",
"-framework", "CoreBluetooth",
"-framework", "CoreLocation",
"-framework", "CoreMotion",
"-framework", "CoreText",
"-framework", "UIKit",
"-framework", "QuartzCore",
"-framework", "OpenGLES",
"-framework", "UserNotifications",
"-arch_only", arch,
"-syslibroot", sdkPath(platform),
"-L${sdkPath(platform)}/usr/lib",
"-o", linkerOutput,
compileOutputs
].flatten()
// execute compiler
exec {
executable "clang"
args clangArgs
workingDir compileOutput
}
// execute linker
exec {
executable "libtool"
args linkerArgs
workingDir compileOutput
}
linkerOutputs.add(linkerOutput)
}
def lipoArgs = [
"-create",
linkerOutputs,
"-o",
lipoOutput
].flatten();
// execute lipo to combine all linker output in one archive
exec {
executable "lipo"
args lipoArgs
}
}
build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'org.javafxports:jfxmobile-plugin:1.3.16'
}
}
apply plugin: 'org.javafxports.jfxmobile'
apply from: 'ios-build.gradle'
repositories {
jcenter()
maven {
url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
}
}
mainClassName = 'your.main.class'
dependencies {
compile 'com.gluonhq:charm:5.0.2'
}
jfxmobile {
javafxportsVersion = '8.60.11'
downConfig {
version = '3.8.6'
// Do not edit the line below. Use Gluon Mobile Settings in your project context menu instead
plugins 'display', 'lifecycle', 'statusbar', 'storage'
}
android {
manifest = 'src/android/AndroidManifest.xml'
}
ios {
infoPList = file('src/ios/Default-Info.plist')
forceLinkClasses = [
'com.gluonhq.**.*',
'javax.annotations.**.*',
'javax.inject.**.*',
'javax.json.**.*',
'org.glassfish.json.**.*'
]
}
}
task xcodebuild {
doLast {
xcodebuildIOS("$project.buildDir","$project.projectDir", "Version")
}
}
task installNativeLib (type:Copy, dependsOn: xcodebuild) {
from("$project.buildDir/native")
into("src/ios/jniLibs")
include("*.a")
}
在部署到 iOS、运行 之前:
./gradlew installNativeLib
服务使用
最后,您可以在代码中的任何位置使用该服务:
String version = Services.get(VersionService.class)
.map(VersionService::getVersionName)
.orElse(""));
我想把应用程序版本放到我的胶子应用程序中。但我不知道该怎么做。我需要为此创建服务吗?
有一个非常简单的方法,不需要服务,但它可能会导致错误:
您可以在 AndroidManifest:
中为 Android 维护版本号 code/version<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.package"
android:versionCode="1.1.0"
android:versionName="1.1.0">
在 iOS 上相同,在 Default-Info.plist 中:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>your.bundle.identifier</string>
<key>CFBundleVersion</key>
<string>1.1.0</string>
最后,您可以在代码中保留一个静态字段:
public static final String VERSION_NAME = "1.1.0";
例如,您可以从 NavigationDrawer
访问。
但是,每次发布新版本时都需要手动更新。
为避免错误,您可以设置一些 CI 作业来为您完成。例如,请参阅此 commit,它是移动应用程序发布工作的一部分。
魅力羽绒服
但是,避免发布的版本与代码中的变量不匹配的更明确的方法是添加直接读取这些版本的服务。
像这样:
VersionService.java
package com.gluonhq.charm.down.plugins;
public interface VersionService {
String getVersionName();
}
VersionServiceFactory.java
package com.gluonhq.charm.down.plugins;
import com.gluonhq.charm.down.DefaultServiceFactory;
public class VersionServiceFactory extends DefaultServiceFactory<VersionService> {
public VersionServiceFactory() {
super(VersionService.class);
}
}
Android 包,在 src/android/java
:
AndroidVersionService.java
package com.gluonhq.charm.down.plugins.android;
import android.content.pm.PackageManager;
import com.gluonhq.charm.down.plugins.VersionService;
import javafxports.android.FXActivity;
public class AndroidVersionService implements VersionService {
@Override
public String getVersionName() {
try {
return FXActivity.getInstance().getPackageManager()
.getPackageInfo(FXActivity.getInstance().getPackageName(), 0)
.versionName;
} catch (PackageManager.NameNotFoundException ex) { }
return "";
}
}
IOS 包,在 src/ios/java
:
IOSVersionService.java
package com.gluonhq.charm.down.plugins.ios;
import com.gluonhq.charm.down.plugins.VersionService;
public class IOSVersionService implements VersionService {
static {
System.loadLibrary("Version");
}
@Override
public String getVersionName() {
return getNativeVersion();
}
private static native String getNativeVersion();
}
在src/ios/native
下:
Version.m
#import <UIKit/UIKit.h>
#include "jni.h"
JNIEXPORT jint JNICALL
JNI_OnLoad_Version(JavaVM *vm, void *reserved)
{
#ifdef JNI_VERSION_1_8
//min. returned JNI_VERSION required by JDK8 for builtin libraries
JNIEnv *env;
if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_8) != JNI_OK) {
return JNI_VERSION_1_4;
}
return JNI_VERSION_1_8;
#else
return JNI_VERSION_1_4;
#endif
}
JNIEXPORT jstring JNICALL Java_com_gluonhq_charm_down_plugins_ios_IOSVersionService_getNativeVersion
(JNIEnv *env, jclass jClass)
{
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
return (*env)->NewStringUTF(env, [version cStringUsingEncoding:NSASCIIStringEncoding]);
}
在根级别构建文件:
ios-build.gradle
if (System.getProperty('os.name').toLowerCase().contains("mac")) {
new ByteArrayOutputStream().withStream { os ->
exec {
args '-version', '-sdk', 'iphoneos', 'SDKVersion'
executable 'xcodebuild'
standardOutput = os
}
ext.IOS_VERSION = os.toString().trim()
}
} else {
ext.IOS_VERSION = ""
}
ext.IS_DEBUG_NATIVE = Boolean.parseBoolean(System.getProperty("IS_DEBUG_NATIVE", "false"))
def sdkPath(String platform) {
return "/Applications/Xcode.app/Contents/Developer/Platforms/${platform}.platform/Developer/SDKs/${platform}${IOS_VERSION}.sdk";
}
ext.xcodebuildIOS = {buildDir, projectDir, name ->
if (!file(sdkPath('iPhoneOS')).exists()) {
println "Skipping xcodebuild"
return
}
// define statics do being able to configure the input/output files on the task
// for faster builds if nothing changed
def buildSystems = ["iPhoneOS+arm64",
"iPhoneOS+armv7",
"iPhoneSimulator+i386",
"iPhoneSimulator+x86_64"]
def linkerOutputs = []
def lipoOutput = "$buildDir/native/lib${name}.a"
def nativeSources = ["$projectDir/src/ios/native/${name}.m"]
// the actual task action
buildSystems.each { buildSystem ->
def (platform, arch) = buildSystem.tokenize("+");
def compileOutput = "$buildDir/native/$arch"
def compileOutputs = ["$buildDir/native/$arch/${name}.o"]
def linkerOutput = "$buildDir/native/$arch/lib${name}.a"
new File(compileOutput).mkdirs();
def clangArgs = [
"-x", "objective-c",
"-miphoneos-version-min=6.0",
"-fmessage-length=0",
"-std=c99",
"-fno-common",
"-Wall",
"-fno-strict-aliasing",
"-fwrapv",
"-fpascal-strings",
"-fobjc-abi-version=2",
"-fobjc-legacy-dispatch",
"-I" + System.getenv("JAVA_HOME") + "/include",
"-I" + System.getenv("JAVA_HOME") + "/include/darwin",
"-c",
IS_DEBUG_NATIVE ? ["-O0", "-DDEBUG", "-g"] : ["-O3", "-DNDEBUG"],
"-arch", arch,
"-isysroot",
sdkPath(platform),
nativeSources].flatten()
// "-o", compileOutput,
def linkerArgs = [
"-static",
"-framework", "Foundation",
"-framework", "CoreGraphics",
"-framework", "CoreBluetooth",
"-framework", "CoreLocation",
"-framework", "CoreMotion",
"-framework", "CoreText",
"-framework", "UIKit",
"-framework", "QuartzCore",
"-framework", "OpenGLES",
"-framework", "UserNotifications",
"-arch_only", arch,
"-syslibroot", sdkPath(platform),
"-L${sdkPath(platform)}/usr/lib",
"-o", linkerOutput,
compileOutputs
].flatten()
// execute compiler
exec {
executable "clang"
args clangArgs
workingDir compileOutput
}
// execute linker
exec {
executable "libtool"
args linkerArgs
workingDir compileOutput
}
linkerOutputs.add(linkerOutput)
}
def lipoArgs = [
"-create",
linkerOutputs,
"-o",
lipoOutput
].flatten();
// execute lipo to combine all linker output in one archive
exec {
executable "lipo"
args lipoArgs
}
}
build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'org.javafxports:jfxmobile-plugin:1.3.16'
}
}
apply plugin: 'org.javafxports.jfxmobile'
apply from: 'ios-build.gradle'
repositories {
jcenter()
maven {
url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
}
}
mainClassName = 'your.main.class'
dependencies {
compile 'com.gluonhq:charm:5.0.2'
}
jfxmobile {
javafxportsVersion = '8.60.11'
downConfig {
version = '3.8.6'
// Do not edit the line below. Use Gluon Mobile Settings in your project context menu instead
plugins 'display', 'lifecycle', 'statusbar', 'storage'
}
android {
manifest = 'src/android/AndroidManifest.xml'
}
ios {
infoPList = file('src/ios/Default-Info.plist')
forceLinkClasses = [
'com.gluonhq.**.*',
'javax.annotations.**.*',
'javax.inject.**.*',
'javax.json.**.*',
'org.glassfish.json.**.*'
]
}
}
task xcodebuild {
doLast {
xcodebuildIOS("$project.buildDir","$project.projectDir", "Version")
}
}
task installNativeLib (type:Copy, dependsOn: xcodebuild) {
from("$project.buildDir/native")
into("src/ios/jniLibs")
include("*.a")
}
在部署到 iOS、运行 之前:
./gradlew installNativeLib
服务使用
最后,您可以在代码中的任何位置使用该服务:
String version = Services.get(VersionService.class)
.map(VersionService::getVersionName)
.orElse(""));