m_shige1979のささやかな抵抗と欲望の日々

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

react-native-configで環境変数を参照する3(android編)

前回

m-shige1979.hatenablog.com

今回やること

前回って環境変数を読むのにENVFILEとか設定していましたよね? あれだけではビルド時のアプリ名とか各環境のアプリ名などの調整が困難なので その辺の設定周り

補足

flavorとか利用しますが、厳密に理解はしていないため、 今回はこの設定でできたようなものとなります

参考

ReactNative製アプリのリリースTips(Android編) | スペースマーケットブログ

ReactNativeのAndroid側でFlavorで環境を切り分ける - Qiita

ReactNative(Android)でビルドバリアント毎にapk出力(署名つき) - Qiita

ReactNative 0.60.4、react-native-config を使って環境構築、リリースまで1 - LOCAL-C BLOG

【ReactNative】Androidリリースビルド時のメモ(2019/10/28 追記あり) - Qiita

react-nativeで初めてのnativeアプリリリース(android編)│tech1000+

【ReactNative】Androidリリースをイチからメモ - メモメモメモ

flavorを利用します

android/app/build.gradleへの設定1:defaultConfigにbuild_config_packageの設定を追加

    defaultConfig {
        applicationId "com.sampleconfig01"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0"
        
        // 追加
        resValue "string", "build_config_package", "com.sampleconfig01"
    }

android/app/build.gradleへの設定2:signingConfigsにrelease用の設定を追加

    signingConfigs {
        debug {
            storeFile file('debug.keystore')
            storePassword 'android'
            keyAlias 'androiddebugkey'
            keyPassword 'android'
        }

        // 任意のキーストアファイルを利用
        release {
            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
            }
        }
    }

android/app/build.gradleへの設定3:buildTypesにrelease用の設定を追加

    buildTypes {
        debug {
            signingConfig signingConfigs.debug
        }
        release {
            // Caution! In production, you need to generate your own keystore file.
            // see https://reactnative.dev/docs/signed-apk-android.
            signingConfig signingConfigs.release
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }

android/app/build.gradleへの設定4:flavorの設定を追加

    // applicationVariants are e.g. debug, release
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            // For each separate APK per architecture, set a unique version code as described here:
            // https://developer.android.com/studio/build/configure-apk-splits.html
            // Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
            def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
            def abi = output.getFilter(OutputFile.ABI)
            if (abi != null) {  // null for the universal-debug, universal-release variants
                output.versionCodeOverride =
                        defaultConfig.versionCode * 1000 + versionCodes.get(abi)
            }

        }
    }

    // flavor追加
    flavorDimensions "default"
    productFlavors {
        dev {
            versionName = android.defaultConfig.versionName + '-dev'
            applicationIdSuffix ".dev"
        }
        stg {
            versionName = android.defaultConfig.versionName + '-staging'
            applicationIdSuffix ".stg"
        }
        prd {
            versionName = android.defaultConfig.versionName
        }
    }
}

dependencies {
・
・
・

android/gradle.propertiesにrelease用のキーストアの設定を追加

今回はセキュリティ的な面も含めてデバッグ時のものをコピー

# releaseキーストア設定
MYAPP_RELEASE_STORE_FILE=release.keystore
MYAPP_RELEASE_KEY_ALIAS=androiddebugkey
MYAPP_RELEASE_STORE_PASSWORD=android
MYAPP_RELEASE_KEY_PASSWORD=android

アプリのアイコン名などを環境別に作成

android/app/src配下のディレクトリに以下の構成を追加

※mainやdebugなどはそのままで削除しなくて良い

android/app/src
├── dev
│   └── res
│       └── values
│           └── strings.xml
├── prd
│   └── res
│       └── values
│           └── strings.xml
└── stg
    └── res
        └── values
            └── strings.xml

android/app/src/dev/res/values/strings.xml

<resources>
    <string name="app_name">アプリ開発</string>
</resources>

android/app/src/stg/res/values/strings.xml

<resources>
    <string name="app_name">アプリ受入</string>
</resources>

android/app/src/prd/res/values/strings.xml

<resources>
    <string name="app_name">アプリ本番</string>
</resources>

とりあえず設定は完了

実行

開発用

npx react-native run-android --variant=DevDebug --appIdSuffix dev

検証用

npx react-native run-android --variant=StgDebug --appIdSuffix stg

本番用

npx react-native run-android --variant=PrdDebug


環境別アプリ作成テスト

本番用ビルド

デバッグ時はデバッグアプリとして動作するため、実行時のマシンとデバッグ監視サーバとかが動作し、 また、スマホから実行する際もhttp系で証明書なしでも通信が可能となる

assetsディレクトリ準備

作成されていない場合は作成しておく

android/app/src/main/assets

バンドル作成

npx react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest --assets-dest android/app/build/intermediates/res/merged/release/

アプリ作成

cd android
 ./gradlew assembleDev
 ./gradlew assembleStg
 ./gradlew assemblePrd

作成場所

 % tree app/build/outputs/apk/
app/build/outputs/apk/
├── debug
│   ├── app-debug.apk
│   └── output-metadata.json
├── dev
│   ├── debug
│   │   ├── app-dev-debug.apk
│   │   └── output-metadata.json
│   └── release
│       ├── app-dev-release.apk
│       └── output-metadata.json
├── prd
│   └── debug
│       ├── app-prd-debug.apk
│       └── output-metadata.json
└── stg
    └── debug
        ├── app-stg-debug.apk
        └── output-metadata.json

アプリインストール

adb [-s デバイスID] install app/build/outputs/apk/dev/release/app-dev-release.apk

※apkファイルは環境に合わせて読み替える ※デバイスID未指定の場合は有効なデバイス全てにインストールする

package.json改修

  "scripts": {
    "android": "react-native run-android --variant=DevDebug --appIdSuffix dev",
    "android_dev": "react-native run-android --variant=DevDebug --appIdSuffix dev",
    "android_stg": "react-native run-android --variant=StgDebug --appIdSuffix stg",
    "android_prd": "react-native run-android --variant=PrdDebug",
    "android_bundle": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest --assets-dest android/app/build/intermediates/res/merged/release/",
    "android_release": "yarn android_bundle && cd android && ./gradlew assembleDev && ./gradlew assembleStg && ./gradlew assemblePrd",
    "ios": "react-native run-ios",
    "ios_dev": "echo '.env' > /tmp/envfile && yarn ios",
    "ios_stg": "echo '.env.staging' > /tmp/envfile && yarn ios",
    "ios_prd": "echo '.env.production' > /tmp/envfile && yarn ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint ."
  },