утверждение
Эта статья подходит для фронтенд-инженеров без опыта Android-разработки, пожалуйста, не распыляйтесь на Android-боссов~
Предыстория проекта
Из-за быстрой скорости разработки, более высокой производительности, чем у Hybrid, и некоторых других преимуществ использование ReactNative во фронтенд-разработке увеличивается, но есть и много проблем:
- Трудно отличить среду разработки, тестовую среду и формальную среду.При отправке тестового и формального пакета необходимо вручную изменить многие конфигурации среды (например, запрашиваемый адрес интерфейса и т. д.), что громоздко и подвержено ошибкам
- Чтобы новый пакет перезаписал установку старого пакета, необходимо вручную поддерживать номер версии, увеличивая его перед каждым пакетом.
- Файлы, сгенерированные пакетом, называются app-debug.apk, app-release.apk, которые нелегко отличить и заархивировать.
- воплощать в жизнь
react-native run-android
откроет окно оболочки для запуска js-сервера (новая версия будет открываться повторно), очень раздражает - ...
решение
Экологическое отличие
С точки зрения обычных требований нам нужно различать три среды — среду разработки, тестовую среду и формальную среду (которая также может стать производственной средой). воплощать в жизньreact-native run-android
, по умолчанию используется среда отладки (соответствующая здесь среде разработки), и при упаковке мы обычно выполняемcd android && ./gradlew assembleRelease
, очевидно, что здесь используется среда выпуска (соответствующая формальной среде или рабочей среде), но мы также используем эту команду, когда хотим предоставить тестовые пакеты для инженеров по тестированию, поэтому это вызовет формальный пакет и тестовый пакет. использовать один и тот же набор Среду можно отличить только вручную изменив код.
Затем, чтобы решить вышеуказанные проблемы, нам нужно ввести новую среду — Beta, которая является тестовой средой. Сначала нам нужно изменить проектandroid/app/build.gradle
документ:
// 设置beta版本打包jsbundle
// 如没有设置,则beta版会和debug版一样,读取本地js-server的jsbundle
project.ext.react = [
bundleInBeta: true
]
...
android {
...
buildTypes {
release {
...
}
// 此处增加beta的配置
beta {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
После завершения установки мы выполняем, когда попадаем в тестовый пакет.cd android && ./gradlew assembleBeta
Можно и официальный пакетcd android && ./gradlew assembleRelease
Разница была сделана.
Но здесь мы изменили только команду упаковки, а фактическая информация о конфигурации не переключалась автоматически в зависимости от среды. Затем нам нужно продолжить модифицировать файл gradle, чтобы разные среды считывали разные конфигурации.
android {
...
buildTypes {
release {
...
// 不是开发环境,不是测试环境,所以是正式环境
buildConfigField "boolean", "IS_DEBUG", "false"
buildConfigField "boolean", "IS_DEV", "false"
}
beta {
...
// 不是开发环境,是测试环境,所以是测试环境
buildConfigField "boolean", "IS_DEBUG", "true"
buildConfigField "boolean", "IS_DEV", "false"
}
// 此处增加Debug的配置
debug {
// 是开发环境,是测试环境,所以是开发环境
buildConfigField "boolean", "IS_DEBUG", "true"
buildConfigField "boolean", "IS_DEV", "true"
}
}
}
После настройки в коде Android передаемBuildConfig.IS_DEBUG
,BuildConfig.IS_DEV
Мы можем получить нашу текущую операционную среду, и мы можем легко переключать конфигурацию с помощью кода в соответствии со средой. Но это только уровень Android. Нам также нужно передать эту информацию на уровень RN. В js нам также нужно знать среду запуска. На данный момент нам нужно толькоandroid/app/src/main/java/xxx/MainActivity.java
С помощью нескольких небольших изменений вы можете:
...
public class MainActivity extends ReactActivity {
...
class MyReactDelegate extends ReactActivityDelegate {
final Context context;
public MyReactDelegate(Activity activity, @javax.annotation.Nullable String mainComponentName) {
super(activity, mainComponentName);
context = activity;
}
@javax.annotation.Nullable
@Override
protected Bundle getLaunchOptions() {
Bundle bundle = new Bundle();
bundle.putBoolean("isDebugMode", BuildConfig.IS_DEBUG);
bundle.putBoolean("isDevMode", BuildConfig.IS_DEV);
return bundle;
}
}
}
Затем мы можем получить эти две части информации в корневом элементе RN:
...
class App extends Component {
constructor (props) {
super(props)
console.log('isDebugMode', props.isDebugMode)
console.log('isDevMode', props.isDevMode)
}
...
}
...
然后如何切换配置就不用我多说了吧? ~
Изменение имени пакета и другой информации о пакете
Хотя уже можно различить упаковку среды, три версии установочных пакетов не могут сосуществовать на одном устройстве из-за одного и того же имени пакета, и даже если они могут сосуществовать, имена и значки, отображаемые после установки трех пакетов, тождественны и неразличимы, поэтому нам нужно проделать некоторые операции, чтобы их можно было легко различить.
Изменить имя пакета и отображаемое имя
android/app/build.gradle
документ:
release {
...
// 设置manifest占位符,为了显示不同的软件名
manifestPlaceholders = [
APP_NAME : "@string/app_name"
]
}
beta {
...
//为beta版本的包名添加.beta后缀
applicationIdSuffix ".beta"
// 设置manifest占位符,为了显示不同的软件名
manifestPlaceholders = [
APP_NAME : "@string/app_name_beta"
]
}
debug {
...
//为debug版本的包名添加.debug后缀
applicationIdSuffix ".debug"
// 设置manifest占位符,为了显示不同的软件名
manifestPlaceholders = [
APP_NAME : "@string/app_name_debug"
]
}
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
После этого нам нужно запустить приложение вручную. Но команда разработчиков RN давно об этом подумала, и cli может решить эту проблему через параметры. Мы модифицируем команду запуска, чтобы она былаreact-native run-android --appIdSuffix=debug
Вот и все.
Изменить значок
Это относительно просто, файл значка хранится вandroid/app/src/main/res
Далее (это соответствующий путь Release-версии, Beta-версия заменит main на beta, Debug-версия заменит main на debug, если каталога не существует, его можно создать самостоятельно), и поместите ресурсы в папку соответствующий каталог в соответствии с правилами значков Android. Здесь мы рекомендуем веб-сайт для создания значков приложений в один клик:icon.wuruihong.com/, Примечание. Плата за рекламу не взимается.
Я сделал иконку, чтобы различать окружение~
Автоинкрементный номер версии и модификация имени APK-файла
все еще измененоandroid/app/build.gradle
документ:
...
def versionNamePrefix = "1.0"
// 使用git提交次数作为版本号,可保证递增
def revisionNumber = 'git rev-list HEAD --count'.execute().getText().trim()
// 使用git的describe作为版本描述
def revisionDescription = 'git describe --always'.execute().getText().trim()
def verName = versionNamePrefix + "." + revisionNumber + "." + revisionDescription
android {
...
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.outputFile = new File(output.outputFile.parent, "XXXXX_" + "v" + verName + "_" + buildType.name + ".apk");
}
}
}
Будут сгенерированы имена файлов Apk, похожие на XXXXX_v1.0.214.2837e31_release.apk, XXXXX_v1.0.214.2837e31_beta.apk, XXXXX_v1.0.214.2837e31_debug.apk.
Избегайте запуска всплывающих окон
У этого есть два преимущества: во-первых, при каждом запуске не будет всплывать окно, поэтому это меньше раздражает, во-вторых, при переключении нескольких проектов RN пакеты, прочитанные проектами, не будут вызваны тем, что вы забыли выключить js. -сервер Чжан Гуань и Ли Дай.
Метод реализации очень прост, выполнитьreact-native start & react-native run-android --appIdSuffix=debug --no-packager
То есть для него мы тоже можем настроить скрипт в package.json.
concurrently -r 'react-native start' 'react-native run-android --appIdSuffix=debug --no-packager'
. После этого вы можете напрямую увидеть информацию о js-сервере в текущем окне оболочки~