<meta-data
android:name="JPUSH_APPKEY"
android:value="${jush_appkey_value}" />
<meta-data
android:name="SHOUCANG_CONFIG0"
android:value="${SHOUCANG_CONFIG_VALUE0}" /> build.gradle:buildTypes {
release {
//自定义buildconfig字段
buildConfigField("boolean", "APP_ENV", "true")
//指定签名为release
signingConfig signingConfig.release
//是否开启混淆
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//是否zip优化
zipAlignEnabled true
//删除一些无用资源
shrinkResources false
//
manifestPlaceholders = [
"jush_appkey_value": "release key"
]
}
debug {
//自定义buildconfig字段
buildConfigField("boolean", "APP_ENV", "true")
//指定签名为release
signingConfig signingConfig.release
//是否开启混淆
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//是否zip优化
zipAlignEnabled true
//删除一些无用资源
shrinkResources false
//
manifestPlaceholders = [
"jush_appkey_value": "debug key"
]
}
} 在bulidtypes节点下有release节点和debug节点,正式签名时就会走release节点的下编译脚本,调试签名时就会走debug节点。主要点就是manifestPlaceholders的用法,jpush_appkey对应的就是之前在androidmanifest文件配置的${jush_appkey_value}的这个值。 在程序入口出打上log,用来输出key的值:/**
* 在程序入口出打上log,用来输出key的值bufen
*/
private void jpush_key_manifest_xml_string() {
String jpush_appkey;
try {
ApplicationInfo appInfo = getPackageManager()
.getApplicationInfo(getPackageName(),
PackageManager.GET_META_DATA);
jpush_appkey = appInfo.metaData.getString("JPUSH_APPKEY");
Log.e("jpush_appkey", "jpush_appkey=" + jpush_appkey);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
} 接下来给大家介绍多版本多页面多apk的配置切换方法:举个例子:如果你要一次性打七个版本,而且七个版本都是不同的页面,但是页面各个模块大体一样,只是顺序和大小不同,你要怎么做,别告诉我写七个页面分别打版哈~太low了~you know~这里就利用多版本打版和manifestPlaceholders来实现需求。 首先是build.gradle:apply plugin: 'com.android.application'
apply plugin: 'android-apt'
def demo = '0000';//DemoAPK
def demo1 = '0001';//DemoAPK1
def demo2 = '0002';//DemoAPK2
def demo3 = '0003';//DemoAPK3
def demo4 = '0004';//DemoAPK4
def demo5 = '0005';//DemoAPK5
def demo6 = '0006';//DemoAPK6
android {
signingConfigs {
debug {
keyAlias '****'
keyPassword '****'
storeFile file('签名文件.jks路径')
storePassword '****'
}
release {
keyAlias '****'
keyPassword '****'
storeFile file('签名文件.jks路径')
storePassword '****'
}
}
compileSdkVersion 25
buildToolsVersion "25.0.2"
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
}
defaultConfig {
applicationId "com.shining.p010_recycleviewall"
minSdkVersion 18
targetSdkVersion 23
versionCode 1
versionName "1.0"
multiDexEnabled true
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
ndk {
moduleName "native-modbus-jni,libxmediaplayer"
ldLibs "log", "z", "m", "android", "c"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
sourceSets.main {
jni.srcDirs = []
//LOCAL_LDFLAGS += -fuse-ld=bfd
//jni.srcDirs 'src/main/jni'
jniLibs.srcDir 'src/main/libs'
}
signingConfig signingConfigs.debug
manifestPlaceholders = [
SHOUCANG_CONFIG_VALUE0: ".shoucang.factorys.ShoucangFactory0"
]
}
buildTypes {
release {
minifyEnabled true
zipAlignEnabled true
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
}
def int minSdk = 18;
def int targetSdk = 23;
def String appId = 'com.shining.p010_recycleviewall';
def int vCode = 1;
def String vNameCode = vCode + "";
productFlavors {
//demo
DemoAPK {
minSdkVersion minSdk
applicationId appId
targetSdkVersion targetSdk
versionCode vCode
versionName "DemoAPK_" + "T_" + demo
multiDexEnabled true
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
ndk {
moduleName "native-modbus-jni,libxmediaplayer"
ldLibs "log", "z", "m", "android", "c"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir 'src/main/libs'
}
signingConfig signingConfigs.debug
}
//demo1
DemoAPK1 {
minSdkVersion minSdk
applicationId appId
targetSdkVersion targetSdk
versionCode vCode
versionName "DemoAPK1_" + "T_" + demo1
multiDexEnabled true
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
ndk {
moduleName "native-modbus-jni,libxmediaplayer"
ldLibs "log", "z", "m", "android", "c"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir 'src/main/libs'
}
signingConfig signingConfigs.debug
}
//demo2
DemoAPK2 {
minSdkVersion minSdk
applicationId appId
targetSdkVersion targetSdk
versionCode vCode
versionName "DemoAPK2_" + "T_" + demo2
multiDexEnabled true
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
ndk {
moduleName "native-modbus-jni,libxmediaplayer"
ldLibs "log", "z", "m", "android", "c"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir 'src/main/libs'
}
signingConfig signingConfigs.debug
}
//demo3
DemoAPK3 {
minSdkVersion minSdk
applicationId appId
targetSdkVersion targetSdk
versionCode vCode
versionName "DemoAPK3_" + "T_" + demo3
multiDexEnabled true
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
ndk {
moduleName "native-modbus-jni,libxmediaplayer"
ldLibs "log", "z", "m", "android", "c"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir 'src/main/libs'
}
signingConfig signingConfigs.debug
}
//demo4
DemoAPK4 {
minSdkVersion minSdk
applicationId appId
targetSdkVersion targetSdk
versionCode vCode
versionName "DemoAPK4_" + "T_" + demo4
multiDexEnabled true
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
ndk {
moduleName "native-modbus-jni,libxmediaplayer"
ldLibs "log", "z", "m", "android", "c"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir 'src/main/libs'
}
signingConfig signingConfigs.debug
}
//demo5
DemoAPK5 {
minSdkVersion minSdk
applicationId appId
targetSdkVersion targetSdk
versionCode vCode
versionName "DemoAPK5_" + "T_" + demo5
multiDexEnabled true
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
ndk {
moduleName "native-modbus-jni,libxmediaplayer"
ldLibs "log", "z", "m", "android", "c"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir 'src/main/libs'
}
signingConfig signingConfigs.debug
}
//demo6
DemoAPK6 {
minSdkVersion minSdk
applicationId appId
targetSdkVersion targetSdk
versionCode vCode
versionName "DemoAPK6_" + "D_" + demo6
multiDexEnabled true
renderscriptTargetApi 19
renderscriptSupportModeEnabled true
ndk {
moduleName "native-modbus-jni,libxmediaplayer"
ldLibs "log", "z", "m", "android", "c"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir 'src/main/libs'
}
signingConfig signingConfigs.debug
}
}
// 自定义输出配置
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
// def fileName = "UerbT_v${variant.versionName}_${releaseTime()}_${variant.flavorName}.apk"
def fileName = "${variant.versionName}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
productFlavors.all { flavor ->
def currentMode = flavor.versionName.split("_")[2]
def currentEnvironment = flavor.versionName.split("_")[1]
def stValue = true
// t == currentEnvironment 以前的判断条件
if (currentEnvironment.endsWith("T")) {//判断是否为测试版 是否以T结尾
stValue = false
} else {
stValue = true
}
if (currentMode == demo) {
flavor.manifestPlaceholders = [SHOUCANG_CONFIG_VALUE: ".shoucang.factorys.ShoucangFactory", STATISTICS_VALUE: stValue]
} else if (currentMode == demo1) {
flavor.manifestPlaceholders = [SHOUCANG_CONFIG_VALUE: ".shoucang.factorys.ShoucangFactory1", STATISTICS_VALUE: stValue]
} else if (currentMode == demo2) {
flavor.manifestPlaceholders = [SHOUCANG_CONFIG_VALUE: ".shoucang.factorys.ShoucangFactory2", STATISTICS_VALUE: stValue]
} else if (currentMode == demo3) {
flavor.manifestPlaceholders = [SHOUCANG_CONFIG_VALUE: ".shoucang.factorys.ShoucangFactory3", STATISTICS_VALUE: stValue]
} else if (currentMode == demo4) {
flavor.manifestPlaceholders = [SHOUCANG_CONFIG_VALUE: ".shoucang.factorys.ShoucangFactory4", STATISTICS_VALUE: stValue]
} else if (currentMode == demo5) {
flavor.manifestPlaceholders = [SHOUCANG_CONFIG_VALUE: ".shoucang.factorys.ShoucangFactory5", STATISTICS_VALUE: stValue]
} else if (currentMode == demo6) {
flavor.manifestPlaceholders = [SHOUCANG_CONFIG_VALUE: ".shoucang.factorys.ShoucangFactory6", STATISTICS_VALUE: stValue]
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.0'
compile 'com.android.support:recyclerview-v7:25.3.0'
compile 'com.android.support:design:25.3.0'
compile 'com.android.support:cardview-v7:25.3.0'
// local jar file
compile files('libs/alipay-sdk-java20161226110022.jar')
compile files('libs/alipay-sdk-java20161226110022-source.jar')
compile files('libs/commons-logging-1.1.1.jar')
compile files('libs/commons-logging-1.1.1-sources.jar')
//the third file
compile 'com.jakewharton:butterknife:8.2.1'
apt 'com.jakewharton:butterknife-compiler:8.2.1'
testCompile 'junit:junit:4.12'
compile 'com.geeklx:library_hios:1.0.4'
compile project(':glin')
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.alibaba:fastjson:1.2.17'
compile 'com.squareup.okio:okio:1.9.0'
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.nineoldandroids:library:2.4.0'
compile files('libs/libammsdk.jar')
} 接着就是多版本的代码判断书写: @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
//TODO 多版本切换 写此方法bufen
which_version();
// ShoucangConfig0.config();//manifestPlaceholders的妙用
super.onCreate(savedInstanceState);
}
private void which_version() {
if (ConstantNetUtil.VERSION_APK == NetConfig.version_name0) {
ShoucangConfig.config();
} else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name1) {
ShoucangConfig1.config();
} else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name2) {
ShoucangConfig2.config();
} else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name3) {
ShoucangConfig3.config();
} else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name4) {
ShoucangConfig4.config();
} else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name5) {
ShoucangConfig5.config();
} else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name6) {
ShoucangConfig6.config();
}
}
//TODO 多版本模式bufen
SparseArrayCompat<Class<? extends BaseFragment>> array = which_version_fragment_config();//demo
private SparseArrayCompat<Class<? extends BaseFragment>> which_version_fragment_config() {
if (ConstantNetUtil.VERSION_APK == NetConfig.version_name0) {
return ShoucangConfig.getFragments();
} else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name1) {
return ShoucangConfig1.getFragments();
} else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name2) {
return ShoucangConfig2.getFragments();
} else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name3) {
return ShoucangConfig3.getFragments();
} else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name4) {
return ShoucangConfig4.getFragments();
} else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name5) {
return ShoucangConfig5.getFragments();
} else if (ConstantNetUtil.VERSION_APK == NetConfig.version_name6) {
return ShoucangConfig6.getFragments();
}
return ShoucangConfig.getFragments();
} 这样跑完apk你会发现会有神奇的事情发生,如下图:(不同的apk版本出来的页面也是不同的,但是只用了一份代码。)
图2:
这样做的好处在于,如果你的apk版本很多,需要给很多合作厂商提供定制化页面,就可以用上了~ 卧槽,今天喷了好多,希望大家回去自己细化一下,能帮到你~
地址:https://github.com/geeklx/MyApplication/tree/master/p027_daojishi_manifestPlaceholders我似乎找不到一种优雅的方式来做到这一点......给定一个日期,我如何找到下一个星期二,即日历月的第2个或第4个星期二?例如:给定2012-10-19然后返回2012-10-23或给定2012-10-31然后返回2012-11-13OctoberNovemberSuMoTuWeThFrSaSuMoTuWeThFrSa12345612378910111213456789101415161718192011121314151617212223242526271819202122232428293031252627282930 最佳答案
首先,DateTime格式变量似乎没有在任何地方记录,因此对可以在rubydocs中向我展示此内容的任何人+1。其次,在查看Date.strftime函数代码时,我没有看到任何可以让我执行以下操作的内容:2010年9月9日,星期四有人知道这是否可行吗? 最佳答案 您可能想要takealookhere.总结time=DateTime.nowtime.strftime("%A,%B#{time.day.ordinalize}%Y")请注意,您在纯Ruby(2.0)中运行,您需要调用:require'active_support/core
这个赛题的训练数据其实和去年是一样的,只是是语义分割的评价指标改成了类似实例分割的指标。1.赛道背景变化检测对“耕地红线”、土地利用监管等应用具有重要意义。利用多时相遥感数据,采用多种图像处理和模式识别方法提取变化信息,并定量分析和确定地表变化的特征与过程,便是遥感变化检测的本质。传统遥感行业基于人工两期影像标注从而判别地物时相变化的方法受限于效率低、成本高等问题,难以满足实际应用需求,本赛道希望遴选出高效的遥感图像变化检测算法模型,对图像中的变化图斑信息进行高效识别,提高空间信息网络建设中遥感图像快速变化识别能力。2.赛道任务变化检测赛道力求对通过前后两时相的遥感影像,提取出地物发生变化的斑
实现商品详情页json里边设置一下页面标题"navigationBarTitleText":"商品详情"界面组成上方由一个轮播图展示,中间为商品信息,后台会返回图文详情富文本,前台只需赋值下方固定一个工具栏客服分享购物车添加购物车立即购买界面编写分享是将一个按钮隐藏且将其定位在分享处,客服也是一样的加入购物车:如果已经加入则提示已经加入…view>viewclass=
我一直在使用Protractor进行测试,除了通过css之外无法引用该元素,因为它只具有给定的类属性。问题是有超过7个元素具有此类名称。因此我使用语法element.all(by.css('h4.ng-binding')).first();对于第一个,它工作正常,但对于其他人,它不起作用!我使用与第一个逻辑相同的逻辑。这是我的代码片段,供其他人找到它们。element.all(by.css('h4.ng-binding')).second();element.all(by.css('h4.ng-binding')).third();element.all(by.css('h4.ng-b
今天只有1道题,属于动态规划的01背包问题的应用。首先理解一下动态规划的01背包问题。推荐一个视频,动态规划DP0-1背包,这是我认为讲得最为通透的。很多讲解动态背包问题的,一上来就画二维表格,遍历背包或者遍历容量,其实本质上,根本就看不懂那个二维表格是什么意思,为什么容量每次都要从0开始遍历。从原理上讲,容量从0开始只是一种假设,为的是让后面的背包如果装东西了,那么背包容量就会减少,再减少了容量后,怎么挑选物品才会使得质量最高,因此需要从0遍历,这些都是起了给后面的递归初始化一个值的作用。 小偷偷东西,有一个8容量背包,那么他开始从编号4开始偷(也可以从编号1开始偷),他有两种选择,偷或者不
我看过thisquestionhere.但这似乎对我不起作用,因为我不确定FranciscoRomero(选择的答案)在他说idea.config.path和idea时说了什么.系统路径。我不确定我到底应该编辑什么,而且这个问题的其他答案都没有帮助。我只想能够将此文件夹正确移动到我的E:驱动器,然后能够从那里使用AndroidStudio。我的路径是C:\Users\NAME\.AndroidStudio3.1如果有帮助,我在Windows笔记本电脑上。 最佳答案 我可能来晚了,但请按照以下步骤将.AndroidStudioX.Y移
文章目录1.绘制圆锥2.绘制圆柱3.绘制长方体4.绘制球形5.绘制箭头6.绘制坐标轴7.绘制多边形和顶点8.一次绘制多个类型1.绘制圆锥用o3d.geometry.TriangleMesh.create_cone来绘制圆锥,radius控制其半径,height控制其高度importopen3daso3dcone=o3d.geometry.TriangleMesh.create_cone(radius=1.0,height=2.0,resolution=20,split=1)cone.compute_vertex_normals()cone.paint_uniform_color([0,1,0]
文章目录第四章网络层:数据平面1、导论1.1网络层:数据平面1.2网络层:数据平面、控制平面1.3网络层:控制平面2、路由器组成2.1路由器结构概述2.2输入端口功能2.3最长前缀匹配2.4输入端口缓存2.5交换结构2.6输出端口2.7调度机制3、IP:InternetProtocol3.1数据报格式3.2分片和重组3.3IPV4地址3.4DHCP:DynamicHostConfigurationProtocol3.5NAT:NetworkAddressTranslation3.6IPv64、通用转发和SDN4.1网络层4.2SDN4.3OpenFlow第四章网络层:数据平面1、导论1.1网络
今天继续给大家介绍Linux运维相关知识,本文主要内容是openstackNova节点基本原理。一、OpenstackNova节点简介Nova是openstack中最早出现的模块之一,主要是为openstack提供计算服务。在openstack中,Nova又分为计算节点和控制节点。我们把安装有nova-compute的节点称为计算节点,其他的节点称为控制节点。nova的计算节点只负责创建虚拟机,而nova的控制节点负责控制。Nova主要有以下服务:1、API。负责接收和响应外部请求,支持openstackapi、EC2(亚马逊云)API等。2、Cert。负责进行身份认证。3、Scheduler