最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • React-Native开发如何通过原生(android)区分开发/测试/生产环境

    正文概述 掘金(大古同学)   2021-03-19   649

    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_DEBUGBuildConfig.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
    

    参考文档

    1. 掘金
    2. codepush官方-配置多环境
    3. 简书-Gradle之resValue自定义资源
    4. react-native官方-打包APK

    起源地下载网 » React-Native开发如何通过原生(android)区分开发/测试/生产环境

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元