Code Push 热更新使用详细说明和教程



  • CodePush

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

    流程

    1. 安装 CodePush CLI
    2. 创建一个CodePush 账号
    3. 在CodePush服务器注册app
    4. 在app上添加CodePush SDK,配置升级相关代码。ReactNative可以参考这里
    5. 更新代码后,发布一个应用更新到服务器
    6. app收到升级推送

    一、安装CodePush CLI

    管理 CodePush 账号需要通过 NodeJS-based CLI.
    只需要在控制台输入 npm install -g code-push-cli,就可以安装了。
    安装完毕后,输入 code-push -v查看版本代表成功。
    目前我的版本是 1.1.1-beta


    二、创建CodePush账号

    在控制台输入 code-push register 后,将会打开一个网页进行注册
    CodePush账号支持 github和 Microsofe,选其中一个就可以了。
    我选择的是 github,授权完毕后,网页将会显示一个token,复制它到控制台的中就成功了。

    成功登陆后,你的session文件将会写在 /Users/guanMac/.code-push.config。

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

    三、在CodePush服务器上注册app

    为了让codePush服务器知道你的app,我们需要向它注册app: code-push app add <appName>,就可以了。

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

    四、在app中添加SDK,配置相关代码

    由于我目前只开发了android,以下就以android为例。

    第一步。在应用中安装react-native插件,npm install --save react-native-code-push

    第二步。在Anroid project中安装插件。
    CodePush提供了两种方式:RNPMManual
    如果你不想依赖其他工具或者愿意走多几步额外的步骤,可以使用 Manual。不过像我这么懒的代码从业者,毫不犹豫地选择了 RNPM 这个实用工具。

    第三步 运行 npm i rnpm 安装 RNPM。

    第四步 运行 rnpm link react-native-code-push。这条命令将会自动帮我们在anroid文件中添加好设置(其实就是通过Manual的安装步骤)

    第五步android/app/build.gradle文件里面添加额为的创建任务:

        apply from "react.gradle"
        apply from "../../node_modules/react-native-code-push/android/codepush.gradle"
    
    

    第六步 运行 code-push deployment ls <appName>获取 部署秘钥。默认的部署名是 staging,所以 部署秘钥(deployment key ) 就是 staging的可以。

    第七步 添加配置。我们需要让app向CodePush咨询JS bundle的所在位置,这样CodePush就可以控制版本。更新 MainActivity.java文件:

     //1.引用包
     import com.microsoft.codepush.react.CodePush;
     public class MainActivity extends ReactActivity {
     //2.覆盖 getJSBundleFile 方法,让CodePush决定当app启动时,去哪里加载 JS bundle
        @Override
        protected String getJSBundleFile(){
            return CodePush.getBundleUrl():
        }
        
        @Override 
        protected List<ReactPackage> getPackages(){
            //实例化 CodePush运行时,把它添加到 packages,填写正确的 部署秘钥( deployment key)
            return Arrays.<ReactPackage> as List(
                new MainReactPackage(),
                new CodePush("deployment-key-here" , this , BuildCofig.DEBUG)
            )
        }
        
     }
     
    

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

        android{
            defaultConfig{
                versionName "1.0.0"
            }
        }
    

    第九步 CodePush 插件下载和关联完毕后,就剩下在应用中部署更新控制策略:

    • 在 js中加载 CodePush模块: import codePush from 'react-native-code-push'
    • componentDidMount中调用 sync方法,后台请求更新 codePush.sync()

    以上就是在app中添加sdk和配置了。具体的还可以参考官方文档

    部署app相关命令
    • code-push deployment add <appName> 部署
    • code-push deployment rename <appName> 重命名
    • code-push deployment rm <appName> 删除部署
    • code-push deployment ls <appName> 列出应用的部署情况
    • code-push deployment ls <appName> -k 查看部署的key
    • code-push deployment history <appName> <deploymentNmae> 查看历史版本(Production 或者 Staging)

    发布更新

    发布更新之前,需要先把 js打包成 bundle,以下是anroid的做法:

    第一步 在 工程目录里面新增 bundles文件:mkdir bundles

    第二步 运行命令打包 react-native bundle --platform 平台 --entry-file 启动文件 --bundle-output 打包js输出文件 --assets-dest 资源输出目录 --dev 是否调试
    这是我的打包命名: react-native bundle --platform android --entry-file index.android.js --bundle-output ./bundles/index.android.bundle --dev false
    需要注意的是:

    • 忽略了资源输出是因为 输出资源文件后,会把bundle文件覆盖了
    • 输出的bundle文件名不叫其他,而是 index.android.bundle,是因为 在debug模式下,工程读取的bundle就是叫做 index.android.buundle
    • 平台可以选择 android 或者 ios。
    • 具体的命令可以参考这里

    打包bundle结束后,就可以通过CodePush发布更新了。在控制台输入

    code-push release <应用名称> <Bundles所在目录> <对应的应用版本>
        --deploymentName 更新环境
        --description 更新描述
        --mandatory 是否强制更新
    

    注意:

    • CodePush默认是更新 staging 环境的,如果是staging,则不需要填写 deploymentName。
    • 如果有 mandatory 则会让客户端强制更新
    • 对应的应用版本(targetBinaryVersion)是指当前app的版本,而不是你填写的更新版本。譬如客户端版本是 1.0.0,如果我们需要更新客户端,那么targetBinaryVersion填的就是 1.0.0。(踩了坑,半夜调试到哭了- -)
    • 在控制台输入 code-push deployment history <appName> Staging 可以看到版本更新的时间、描述等等属性。

    这是我的输入

    code-push release Equipment ./bundles 1.0.1

    CodePush还可以进行很多种更新控制

    # Release a mandatory update with a changelog
    code-push release-react MyApp ios -m --description "Modified the header color"
    
    # Release an update for an app that uses a non-standard entry file name, and also capture
    # the sourcemap file generated by react-native bundle
    code-push release-react MyApp ios --entryFile MyApp.js --sourcemapOutput ../maps/MyApp.map
    
    # Release a dev Android build to just 1/4 of your end users
    code-push release-react MyApp-Android android --rollout 25% --dev true
    
    # Release an update that targets users running any 1.1.* binary, as opposed to
    # limiting the update to exact version name in the build.gradle file
    code-push release-react MyApp-Android android --targetBinaryVersion "~1.1.0"
    
    

    JS API

    checkForUpdate

    询问服务器是否有新版本。譬如:

        codePush.checkForUpdate()
        .then( (update) =>{
            if( !update ){
                console.log("app是最新版了");
            }else {
                console.log("有更新哦");
            }
        });
    
    getCurrentPackage

    获取当前已安装更新的元数据(描述、安装时间、大小等)。譬如:

        codePush.getCurrenPackage()
        .then( (info) =>{
            console.log(info);
        })
    
    notifyApplicationReady

    通知CodePush进程,一个更新安装好了,当检测并安装更新,这个方法必须被调用。
    否则在app重启时,Codepush会认为update失败,并回滚版本。
    当使用 sync方法时,不需要调用此方法,因为它会默认调用

    restartApp

    立即重启App

    sync

    允许检测更新,下载并安装。除非我们需要自定义UI表现,不然直接用这个方法就可以了。

    注意

    • CodePush只能更新 js或图片,原生代码的改变(二进制打包)是不能通过它更新的。
    • 服务端还木有开源,不能使用自己的服务器
    • 服务端在美国,国内可能会不稳定

    相关链接

    官网

    gitHub README

    CodePush CLI

    更新策略example

    最后

    昨晚弄CodePush大概花了5个小时(主要是踩了坑和出去吃宵夜了哈哈哈),今天整理了一下步骤,希望可以给你带来帮助呗。
    目前也在写一款RN商业应用,使用redux管理状态、实现路由管理中心等等。
    在我的github 上可以看看。刚搭好框架,模块分明,技术文档齐全,也欢迎交流交流。
    由于我不常上论坛,留言可能回答不及时,欢迎加微信聊聊(Guanmac)。



  • 支持!
    那个targetBinaryVersion开始是不好理解, 跟正常的发版(semver)不一样. 不过我一般都是设置为范围值:
    如我要发布一个新的客户端, 版本为1.2.3. 那么发布的codepush更新使用的targetBinaryVersion设置为">=1.0.0 <1.2.3"


登录后回复