ReactNative在前端开发中的使用日渐增多,但是随之而来也产生了很多问题:
- 开发环境、测试环境、正式环境难以区分,发测试和正式包时需要手动修改很多关于环境的配置(如请求的接口地址等),繁琐且容易出错
- 为了新包可以覆盖安装老包,每次打包前还需要手动维护版本号使其递增
- 打包生成文件名为app-debug.apk、app-release.apk,不便于区分和存档
一. 开发需求
环境区分
正常需求来讲,我们需要区分三种环境——开发环境、测试环境、正式环境(也可以成为生产环境)。执行react-native run-android
时,默认是使用了Debug环境(此处对应为开发环境),而打包时我们通常会执行cd android && ./gradlew assembleRelease
,很明显可以看出这里使用的是Release环境(此处对应正式环境或生产环境),但是我们要为测试工程师提供测试包时也是使用这个命令,所以就会造成正式包和测试包使用同一套环境,只能靠手动修改代码来完成环境区分。
那么,为了解决上述问题,我们需要引入一个新的环境——Beta,也即为测试环境
包名及包其他信息修改
上面虽说已经可以区分环境打包,但由于包名相同,三个版本的安装包并不能在一台设备上共存,且即使可以共存,三个包安装后显示的名称已经图标均完全相同无法区分,所以我们需要做一些操作使得它们可以被很容易区分出来。
二. 如何进行配置
android/gradle.properties
MYAPP_RELEASE_STORE_FILE=test.keystore
MYAPP_RELEASE_KEY_ALIAS=my-key-alias
MYAPP_RELEASE_STORE_PASSWORD=***
MYAPP_RELEASE_KEY_PASSWORD=***
MYAPP_RELEASE_STORE_FILE_PRO=pro.keystore
MYAPP_RELEASE_KEY_ALIAS_PRO=my-key-alias
MYAPP_RELEASE_STORE_PASSWORD_PRO=***
MYAPP_RELEASE_KEY_PASSWORD_PRO=***
android/app/build.gradle
:
....
project.ext.react = [
...
// 设置beta版本打包jsbundle
// 如没有设置,则beta版会和debug版一样,读取本地js-server的jsbundle
bundleInBeta: true,
]
...
signingConfigs {
debug {
storeFile file('debug.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
// 从 gradle.properties 读取不同环境的签名
beta {
if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
storeFile file(MYAPP_RELEASE_STORE_FILE)
storePassword MYAPP_RELEASE_STORE_PASSWORD
keyAlias MYAPP_RELEASE_KEY_ALIAS
keyPassword MYAPP_RELEASE_KEY_PASSWORD
}
}
release {
if (project.hasProperty('MYAPP_RELEASE_STORE_FILE_PRO')) {
storeFile file(MYAPP_RELEASE_STORE_FILE_PRO)
storePassword MYAPP_RELEASE_STORE_PASSWORD_PRO
keyAlias MYAPP_RELEASE_KEY_ALIAS_PRO
keyPassword MYAPP_RELEASE_KEY_PASSWORD_PRO
}
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
// 是开发环境,是测试环境,所以是开发环境
buildConfigField "boolean", "IS_DEBUG", "true"
buildConfigField "boolean", "IS_DEV", "true"
//为debug版本的包名添加.debug后缀
applicationIdSuffix ".debug"
// 设置manifest占位符,为了显示不同的软件名
manifestPlaceholders = [
APP_NAME : "@string/app_name_debug"
]
resValue "string", "CodePushDeploymentKey", "w-rRMe60d0kaFD8mPM56gb58XJQXvAzxbTavs"
matchingFallbacks = ['debug']
}
beta {
signingConfig signingConfigs.beta
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
// 不是开发环境,是测试环境,所以是测试环境
buildConfigField "boolean", "IS_DEBUG", "true"
buildConfigField "boolean", "IS_DEV", "false"
//为测试版本的包名添加.beta
applicationIdSuffix ".beta"
// 设置manifest占位符,为了显示不同的软件名
manifestPlaceholders = [
APP_NAME : "@string/app_name_beta"
]
resValue "string", "CodePushDeploymentKey", "******"
matchingFallbacks = ['beta','debug','release',]
}
release {
signingConfig signingConfigs.release
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
// 不是开发环境,不是测试环境,所以是正式环境
buildConfigField "boolean", "IS_DEBUG", "false"
buildConfigField "boolean", "IS_DEV", "false"
// 设置manifest占位符,为了显示不同的软件名
manifestPlaceholders = [
APP_NAME : "@string/app_name"
]
resValue "string", "CodePushDeploymentKey", "*****"
matchingFallbacks = ['release']
}
}
....
设置好之后,在Android的代码中,我们通过BuildConfig.IS_DEBUG
、BuildConfig.IS_DEV
就可以获取到我们当前的运行环境了,我们根据环境,通过代码就很容易进行配置的切换。但这仅仅是Android的层面,我们还需要将这个信息传递给RN层面,在js中也需要知道运行环境,这时候只需要对android/app/src/main/java/xxx/MainActivity.java
做些小改动就可以:
android/app/src/main/java/xxx/MainActivity.java
package com.beesrv.www;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
import android.os.Bundle;
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "demoapp";
}
// 注意这下面的代码
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
@Override
protected Bundle getLaunchOptions() {
Bundle bundle = new Bundle();
bundle.putBoolean("isDebugMode", BuildConfig.IS_DEBUG);
bundle.putBoolean("isDevMode", BuildConfig.IS_DEV);
return bundle;
}
};
}
}
android/app/src/main/AndroidManifest.xml
<application
...
android:label="${APP_NAME}">
<activity
...
android:name=".MainActivity"
android:label="${APP_NAME}">
...
</activity>
...
</application>
android/app/src/main/res/values/strings.xml
<resources>
<string name="app_name">软件XXX</string>
<string name="app_name_beta">软件XXX测试版</string>
<string name="app_name_debug">软件XXX开发版</string>
</resources>
RN代码修改
之后我们在RN的根元素中就能获取到这两个信息:
import React from 'react';
import Index from './app/index';
const App: () => React$Node = props => {
// isDebugMode isDevMode
console.log(props);
return <Index />;
};
export default App;
二. 包名及包其他信息修改
android/app/src/main/AndroidManifest.xml
文件:
<application
...
android:label="${APP_NAME}">
<activity
...
android:name=".MainActivity"
android:label="${APP_NAME}">
...
</activity>
...
</application>
android/app/src/main/res/values/strings.xml
文件:
<resources>
<string name="app_name">软件XXX</string>
<string name="app_name_beta">软件XXX测试版</string>
<string name="app_name_debug">软件XXX开发版</string>
</resources>
!!!需要注意的一点是,修改了启动包名之后,RN默认的启动命令是可以正常打包,但是不会使应用自启,也就是执行react-native run-android
后,我们需要手动启动APP。但RN开发团队早就想到了这点,cli中是可以通过参数来解决这个问题的。我们将启动命令修改为react-native run-android --appIdSuffix=debug
即可。
三. 打包
// window系统下
$ cd android
// 清空编译缓存
$ .\gradlew clean
// 生产环境-打包
$ .\gradlew assembleRelease
// 测试环境- 打包
$ .\gradlew assembleBeta
$ cd ..
// 安装生产环境包到 手机上
$ react-native run-android --variant=release
// 安装测试环境包到手机上
$ react-native run-android --variant=beta --appIdSuffix=beta --no-packager
参考文档
- 掘金
- codepush官方-配置多环境
- 简书-Gradle之resValue自定义资源
- react-native官方-打包APK
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!