美文网首页React Native开发React Native开发经验集
React Native应用部署/热更新/常见问题-CodePu

React Native应用部署/热更新/常见问题-CodePu

作者: 改革路上最靓的崽 | 来源:发表于2020-03-27 16:14 被阅读0次

    什么是CodePush

    CodePush是一个微软开发的云服务器。通过它,开发者可以直接在用户的设备上部署手机应用更新。CodePush相当于一个中心仓库,开发者可以推送当前的更新(包括JS/HTML/CSS/IMAGE等)到CoduPush,然后应用将会查询是否有更新。

    接入流程

    • 安装 CodePush CLI
    • 注册 CodePush账号
    • 在CodePush服务器注册App
    • RN代码中集成CodePush
    • 原生应用中配置CodePush
    • 发布更新的版本

    1. 安装 CodePush CLI

    安装CodePush指令,直接在终端上输入如下命令即可,注意:这个CodePush指令只需要全局安装一次即可,如果第一次安装成功了,那后面就不在需要安装

    npm install -g code-push-cli
    
    image.png

    2、注册 CodePush账号

    注册CodePush账号也很简单,同样是只需简单的执行下面的命令,同样这个注册操作也是全局只需要注册一次即可

    code-push register
    

    注意:当执行完上面的命令后,会自动打开一个授权网页,让你选择使用哪种方式进行授权登录,这里我们统一就选择使用GitHub即可

    image.png

    当注册成功后,CodePush会给我们一个key



    我们直接复制这个key,然后在终端中将这个key填写进去即可,填写key登录成功显示效果如下


    image.png
    我们使用下面的命令来验证我的登录是否成功
    code-push login
    
    image.png

    CodePush注册登录相关命令

    • code-push login 登陆
    • code-push loout 注销
    • code-push access-key ls 列出登陆的token
    • code-push access-key rm <accessKye> 删除某个 access-key

    3、在CodePush服务器注册App

    为了让CodePush服务器有我们的App,我们需要CodePush注册App,输入下面命令即可完成注册,这里需要注意如果我们的应用分为iOS和Android两个平台,这时我们需要分别注册两套key
    应用添加成功后就会返回对应的productionStaging 两个key,production代表生产版的热更新部署,Staging代表开发版的热更新部署,在ios中将staging的部署key复制在info.plist的CodePushDeploymentKey值中,在android中复制在Application的getPackages的CodePush中

    添加iOS平台应用

    code-push app add iOSrn_app ios react-native
    
    image.png
    添加Android平台应用
    code-push app add Androidrn_app Android react-native
    
    image.png

    我们可以输入如下命令来查看我们刚刚添加的App

    code-push app list
    
    image.png

    CodePush管理App的相关命令:

    • code-push app add 在账号里面添加一个新的app
    • code-push app remove 或者 rm 在账号里移除一个app
    • code-push app rename 重命名一个存在app
    • code-push app list 或则 ls 列出账号下面的所有app
    • code-push app transfer 把app的所有权转移到另外一个账号

    4、RN代码中集成CodePush

    首先我们需要安装CodeoPush组件,然后通过link命令添加原生依赖,最后在RN根组件中添加热更新逻辑代码

    安装组件

    npm install react-native-code-push --save
    
    image.png

    添加原生依赖,这里添加依赖我们使用自动添加依赖的方式(RN0.60版本以上的 cli里集成了AutoLink,不用手动link资源了)

    react-native link react-native-code-push
    
    image.png

    我们在RN项目的根组件(例如App.js)中添加热更新逻辑代码如下

    ~
    import codePush from "react-native-code-push";
    const codePushOptions = { checkFrequency: codePush.CheckFrequency.MANUAL };
    export default class App extends Component<{}> {
    
      componentDidMount(){
        codePush.sync({
          updateDialog: true,
          installMode: codePush.InstallMode.IMMEDIATE,
          mandatoryInstallMode:codePush.InstallMode.IMMEDIATE,
          //deploymentKey为刚才生成的,用Platform判断下平台(填写你自己的)
          deploymentKey: Platform.OS === 'ios'?'sYvpLUxuBU9FxICqJ5sccL2GDUPZcc988a73-c917-4dba-bd40-1837998442a6':'fqdFCqLyL4XclNZjWvNN3KNhImR5cc988a73-c917-4dba-bd40-1837998442a6',
          });
      }
    ~
    

    5,模拟器上运行项目

    react-native run-ios
    react-native run-android
    

    5.1 如图下所显打包过程中可能遇到的\color{red}{报错}

    image.png
    错误发生在java编译器执行过程中
    image.png image.png

    看到出来是刚刚引入的Code-Push包,实例化的时候getString方法获取我们之前的DeploymentKey失败.
    getString是android 开发中Context类上的一个获取字符串的方法,在RN中会从根目录下/android/app/src/main/res/values/strings.xml文件中获取值。

    我们打开strings.xml文件后添加这样一行代码:

    <string moduleConfig="true" name="CodePushDeploymentKey"><string moduleConfig="true" name="CodePushDeploymentKey">xxxxxxx你刚刚注册DeploymentKey</string></string>
    

    例如

    image.png
    再次react-native run-android即可成功运行

    6. deployment-key的设置与获取bundle路径 (关于Grande

    • 在上述代码中我们在创建CodePush实例的时候需要设置一个deployment-key,因为deployment-key分生产环境与测试环境两种,所以建议大家在build.gradle中进行设置。在build.gradle中的设置方法如下:
      打开android/app/build.gradle文件,找到android { buildTypes {} }然后添加如下代码即可:
    buildTypes {
        release {
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
            signingConfig signingConfigs.config
           + buildConfigField "String", "CODE_PUSH_KEY", CODE_PUSH_KEY_PRODUCTION
           + buildConfigField "boolean", "IS_CODE_PUSH", "true"
        }
        debug {
           + buildConfigField "String", "CODE_PUSH_KEY", CODE_PUSH_KEY_STAGING
           + buildConfigField "boolean", "IS_CODE_PUSH", "true"
        }
    }
    

    心得:另外,我们也可以将deployment-key存放在gradle.properties中:

    CODE_PUSH_KEY_PRODUCTION="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
    CODE_PUSH_KEY_STAGING="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
    
    image.png
    在android/app/build.gradle设置好deployment-key之后呢,我们就可以这样使用了:

    MainApplication.java下的ReactNativeHost方法中添加

    @Override
    protected String getJSBundleFile() {
        // gradlew assembleRelease会把所有用到的JavaScript代码都打包内置到APK中
        if (BuildConfig.IS_CODE_PUSH) {
            return CodePush.getJSBundleFile(); // code-push热更新
        }
        //return UpdateContext.getBundleUrl(MainApplication.this); // pushy热更新
    } 
    

    7.修改versionName和引入code-push设置。

    在 android/app/build.gradle中有个 android.defaultConfig.versionName属性,我们需要把 应用版本改成 1.0.0(默认是1.0,但是codepush需要三位数)。

    android{
        defaultConfig{
            versionName "1.0.0"
        }
    }
    //文件最下方
    apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"  
    

    \android\app\src\main\java\com\ysty_app3\MainApplication.java添加包

    import com.microsoft.codepush.react.CodePush;
    

    至此Code Push for Android的SDK已经集成完成。

    8、发布更新的版本

    在使用之前需要考虑的是检查更新时机,更新是否强制,更新是否要求即时等

    更新时机

    一般常见的应用内更新时机分为两种,一种是打开App就检查更新,一种是放在设置界面让用户主动检查更新并安装

    • 打开APP就检查更新
      最为简单的使用方式在React Natvie的根组件的componentDidMount方法中通过
      codePush.sync()(需要先导入codePush包:import codePush from 'react-native-code-push')方法检查并安装更新,如果有更新包可供下载则会在重启后生效。不过这种下载和安装都是静默的,即用户不可见。如果需要用户可见则需要额外的配置。具体可以参考codePush官方API文档,部分代码,完整代码请参照文档上面
     codePush.sync({
          updateDialog: true,//code-push 接管更新
          installMode: codePush.InstallMode.IMMEDIATE,
          mandatoryInstallMode:codePush.InstallMode.IMMEDIATE,
          //deploymentKey为刚才生成的,用Platform判断下平台
          deploymentKey: Platform.OS === 'ios'?'IOSKey':'andoridKey',
          });
    

    上面的配置在检查更新时会弹出提示对话框, mandatoryInstallMode表示强制更新,

    • 用户点击检查更新按钮
      在用户点击检查更新按钮后进行检查,如果有更新则弹出提示框让用户选择是否更新,如果用户点击立即更新按钮,则会进行安装包的下载(实际上这时候应该显示下载进度,这里省略了)下载完成后会立即重启并生效(也可配置稍后重启),部分代码如下
    codePush.checkForUpdate(deploymentKey).then((update) => {
        if (!update) {
            Alert.alert("提示", "已是最新版本--", [
                {
                    text: "Ok", onPress: () => {
                    console.log("点了OK");
                }
                }
            ]);
        } else {
            codePush.sync({
                    deploymentKey: deploymentKey,
                    updateDialog: {
                        optionalIgnoreButtonLabel: '稍后',
                        optionalInstallButtonLabel: '立即更新',
                        optionalUpdateMessage: '有新版本了,是否更新?',
                        title: '更新提示'
                    },
                    installMode: codePush.InstallMode.IMMEDIATE,
    
                },
                (status) => {
                    switch (status) {
                        case codePush.SyncStatus.DOWNLOADING_PACKAGE:
                            console.log("DOWNLOADING_PACKAGE");
                            break;
                        case codePush.SyncStatus.INSTALLING_UPDATE:
                            console.log(" INSTALLING_UPDATE");
                            break;
                    }
                },
                (progress) => {
                    console.log(progress.receivedBytes + " of " + progress.totalBytes + " received.");
                }
            );
        }
     }
    

    更新是否要求即时
    在更新配置中通过指定installMode来决定安装完成的重启时机,亦即更新生效时机

    • codePush.InstallMode.IMMEDIATE :安装完成立即重启更新

    • codePush.InstallMode.ON_NEXT_RESTART :安装完成后会在下次重启后进行更新

    • codePush.InstallMode.ON_NEXT_RESUME :安装完成后会在应用进入后台后重启更新

      如何发布CodePush更新包

    工程根目录新增 bundles文件夹:

    mkdir bundles
    

    1.自动生成bundles文件发布:

    code-push release-react 《app名称》《平台》 -t 《版本号》 -d Production --des "描述" -m true
    例如
    code-push release-react weather android --t 1.0.0 -d Production --dev false --des "1.优化操作流程,2.我裂开" --m false
    

    2.手动生成bundles文件发布, 首先在根目录创建bundles文件夹(每次重新生成文件时需删除上次的文件)

    • 单js文件
    1. 创建bundles里的文件
    打包命令
    react-native bundle --platform 平台 --entry-file 启动文件 --bundle-output 打包js输出文件 --assets-dest 资源输出目录 --dev 是否调试 
    
    打包整个项目的js文件,例如: 
    react-native bundle --platform android --entry-file index.js --bundle-output ./bundles/index.android.bundle --dev false
    
    2. 发布更新
    发布命令: 
    code-push release <应用名称> <Bundles所在目录> <对应的应用版本> --deploymentName 更新环境 --description 更新描述 --mandatory 是否强制更新
    
    例如:
    code-push release CodePushDemo-android ./bundles/index.android.bundle 1.0.0 --deploymentName Production --description "热更新" --mandatory true
    
    • js文件+图片资源,–assets-dest 后就是放图片的文件夹路径
    打包命令:–assets-dest 后就是放图片的文件夹路径
    react-native bundle --platform android --entry-file index.js --bundle-output ./bundles/index.android.bundle --assets-dest ./bundles --dev false
    
    发布bundles文件:
    code-push <release/debug> <projectName(与注册的app同名)><bundle文件名> <版本号> --deploymentName 更新环境 --description 更新描述 --mandatory 是否强制更新
    例如:
    code-push release CodePushDemo-android ./bundles 1.0.0  //省略默认是发布Staging
    code-push release CodePushDemo-android ./bundles 1.0.0 -d Production --des "热更新" --mandatory true
    

    需要注意的是:

    • 输出的bundle文件名不叫其他,而是 index.android.bundle,是因为 在debug模式下,
      工程读取的bundle就是叫做 index.android.bundle。
    • 平台可以选择 android 或者 ios。

    查看发布信息

    查看已add appName
    code-push app list 
    
    查看部署的历史版本信息
    code-push deployment ls CodePushDemo-android -k
    

    9,自定义更新窗口

    我们再次打开 app是就可以看到,code-push弹出的 更新提示弹框

    image.png

    这是code-push提供的弹窗,如果需要自定义文字

    修改更新弹出框内容
    进入node_modules->react-native-code-push->Codepush.js修改以下内容

    image.png
    需要更多自定义设置参考https://blog.csdn.net/weixin_42613755/article/details/104964557
    可能出现的问题(react-native run-android)
    1. What went wrong:
      Execution failed for task ':app:mergeDebugResources'.
      Could not read path 'E:\cli3\weather2\android\app\build\intermediates\incremental\mergeDebugResources\merged.dir\values'.
      cd android 执行 gradlew clean解决
    2. [Error:Execution failed for task ':app:transformClassesWithDexForDebug]

    在项目android/app/build.gradle下添加

     defaultConfig {
            ...
            multiDexEnabled true
    }
    

    本片内容借鉴至https://segmentfault.com/a/1190000016273902?utm_source=tag-newest
    可访问 查阅关于ios端的热更新

    相关文章

      网友评论

        本文标题:React Native应用部署/热更新/常见问题-CodePu

        本文链接:https://www.haomeiwen.com/subject/pvfluhtx.html