• 在React Native中集成热更新


    最近,在项目DYTT集成了热更新,简单来说,就是不用重新下载安装包即可达到更新应用的目的,也不算教程吧,这里记录一下。

    1.热更新方案

    目前网上大概有两个比较广泛的方式,分别是

    前者是由ReactNative中文网推出的代码热更新服务,后者是由微软老大哥推出的,当然不仅仅是为React Native,还包括其他原生方式。

    综合考虑之下,选择了react-native-code-push

    2.安装code-push

    1.安装code-push

    npm install -g code-push-cli

    2.注册登录账号

    code-push register

    这时候会自动启动浏览器打开网页并提供一个codePush AccessKey,然后命令行里出现需要输入access key

    输入之后就登录成功了。

    (貌似在本机上以后都不用登录了,暂不清楚保持登录持续多久)

    3.添加一个CodePush应用

    code-push app add myProject android react-native
    注意填写app的名称,OS(android/ios),平台(react-native),并且androidios需要创建两个应用

    创建完成会出现两个key

    name Deployment Key
    Production (一串37位的key)
    Staging (一串37位的key)

    Production是对应生产环境的,Staging是对应开发环境的。

    这个对于我们来说其实没什么区别,只是为了方便测试,所以搞了两个环境

    3.react-native应用接入code-push

    1.安装react-native-code-push

    yarn add react-native-code-push
    

    link

    react-native link react-native-code-push

    2.原生配置

    目前只测试了androidios有兴趣的可以自行测试

    上面提到了两个key值,现在需要配置在原生目录里

    1.打开android/app/build.gradle

    android {
        ...
        buildTypes {
            debug {
                ...
                // Note: CodePush updates should not be tested in Debug mode as they are overriden by the RN packager. However, because CodePush checks for updates in all modes, we must supply a key.
                buildConfigField "String", "CODEPUSH_KEY", '""'
                ...
            }
    
        releaseStaging {
            ...
            buildConfigField "String", "CODEPUSH_KEY", '"<INSERT_STAGING_KEY>"'//注意这里的引号
            ...
        }
    
        release {
            ...
            buildConfigField "String", "CODEPUSH_KEY", '"<INSERT_PRODUCTION_KEY>"'
            ...
        }
    }
    ...
    

    }

    如果遇到打包错误,可加上matchingFallbacks = ['release', 'debug'],不知道是不是个别情况,如果没有的请忽略。

    修改versionName为3位数的版本号(code-push要求)

    defaultConfig {
            applicationId "com.dytt"
            minSdkVersion rootProject.ext.minSdkVersion
            targetSdkVersion rootProject.ext.targetSdkVersion
            versionCode 2
            versionName "2.1.0"//默认为2位版本号
            // ndk {
            //     abiFilters "armeabi-v7a", "x86"
            // }
        }
    release {
                //...
                matchingFallbacks = ['release', 'debug']//加上这一句
                buildConfigField "String", "CODEPUSH_KEY", '"<INSERT_PRODUCTION_KEY>"'
                //...
            }

    2.打开MainApplication.java

    @Override
    protected List<ReactPackage> getPackages() {
        return Arrays.<ReactPackage>asList(
            ...
            new CodePush(BuildConfig.CODEPUSH_KEY, MainApplication.this, BuildConfig.DEBUG), // Add/change this line.
            ...
        );
    }

    这样就实现了key的动态部署,即在什么环境下使用什么key

    以上文档参考自https://github.com/Microsoft/react-native-code-push/blob/master/docs/multi-deployment-testing-android.md

    4.客户端更新策略

    1.导入react-native-code-push

    这里需要在应用的根组件上添加CodePush配置

    import CodePush from "react-native-code-push";

    如果你的环境支持Decorator(修饰符),可以这样

    @codePush(options: CodePushOptions)
    class MyApp extends Component<{}> {}

    普通的写法

    class MyApp extends Component<{}> {}
    MyApp = codePush(codePushOptions)(MyApp);
    export default MyApp;

    这里的codePushOptions是更新的配置选项

    • checkFrequency (codePush.CheckFrequency) 指定您要检查更新的时间,默认为codePush.CheckFrequency.ON_APP_START
    • installMode (codePush.InstallMode) 指定何时安装可选更新,默认为codePush.InstallMode.ON_NEXT_RESTART
    • ...

    详细的配置可参考https://github.com/Microsoft/react-native-code-push/blob/master/docs/api-js.md

    2.更新策略

    默认情况下,CodePush会在app每次启动的时候去检测是否有更新,如果有,app会自动下载并在下次打开app时安装

    这种更新方式是静默的,用户根本察觉不到。

    如果我们需要给一点更新提示,可以使用默认的弹出框,也就是react-native自带的Alert,点击后立即安装

    class MyApp extends Component {}
    MyApp = codePush({
        updateDialog: true,
        installMode: codePush.InstallMode.IMMEDIATE
    })(MyApp);

    当然,你可以对弹出框做少量的自定义,比如标题,按钮的文字等

    updateDialog: {
      optionalIgnoreButtonLabel: '稍后',
      optionalInstallButtonLabel: '立即更新',
      optionalUpdateMessage: '有新版本了,是否更新?',
      title: '更新提示'
    },
    

    这些是默认的更新方式,那么如何自定义呢。

    我们可以用到CodePush.checkForUpdate来手动检查更新,然后弹出一个自定义窗口

    const RemotePackage = await CodePush.checkForUpdate(deploymentKey);
    if(RemotePackage){
      this.modal.init(RemotePackage);//打开弹窗
    }
    这里需要注意的是,在checkForUpdate(或其他需要填写deploymentKey的地方)的时候,如果在debug模式下,如果不填写deploymentKey,会提示缺少deploymentKey,我们可以临时写一个固定的方便测试。在正式环境下,这里是不需要填写,它会根据系统自动获取我们在之前配置的那些deploymentKey

    然后可以通过RemotePackage.downloadLocalPackage.install来完成下载和安装

    install = async () => {
        LayoutAnimation.easeInEaseOut();
        this.setState({status:1})//download
        const LocalPackage = await this.RemotePackage.download((progress)=>{
            this.setState({
                receivedBytes:progress.receivedBytes
            })
            Animated.timing(
                this.width,
                {
                    toValue: parseFloat(progress.receivedBytes / progress.totalBytes).toFixed(2),
                    duration: 150
                }
            ).start();
        })
        this.setState({status:2})//downloadComplete
        await LocalPackage.install(LocalPackage.isMandatory?CodePush.InstallMode.IMMEDIATE:CodePush.InstallMode.ON_NEXT_RESUME);
        if(!LocalPackage.isMandatory){
            this.setState({status:3})
            this.setVisible(false);
        }else{
            ToastAndroid && ToastAndroid.show('下次启动完成更新', ToastAndroid.SHORT);
        }
    }

    具体实现可以参考项目DYTT

    3.打包Release

    cd android
    

    生成Release(Production)包

    gradlew assembleRelease

    生成Release(Staging)包

    gradlew assembleReleaseStaging

    其实都一样,只是环境区别

    5.发布code-push更新

    这一步很简单,集成了打包和发布

    code-push release-react dyttAndroid android --t 2.1.0 --dev false --d Production --des "1.修复了已知BUG
     2.测试code push" --m true

    这里注意--t 2.1.0,有以下几种规则

    1.2.3 仅仅只有1.2.3的版本
    
    • 所有版本

    1.2.x 主要版本1,次要版本2的任何修补程序版本

    1.2.3 - 1.2.7 1.2.3版本到1.2.7版本

    >=1.2.3 <1.2.7 大于等于1.2.3版本小于1.2.7的版本

    ~1.2.3 大于等于1.2.3版本小于1.3.0的版本

    ^1.2.3 大于等于1.2.3版本小于2.0.0的版本

    --d表示开发版本,可选择ProductionStaging

    --m表示是否强制更新

    当然还有很多操作,比如删除某些更新,回滚等,可以参考官方文档https://github.com/Microsoft/react-native-code-push

    小节

    总的来说,这次热更新集成还是挺容易,里面碰到的几个误区在上面也已经提到过,欢迎大家多多关注我的项目DYTT^^

    原文地址:https://segmentfault.com/a/1190000017856985

  • 相关阅读:
    Java代码实现依赖注入
    Linux shell脚本的字符串截取
    Android教程:wifi热点问题
    Android framework层实现实现wifi无缝切换AP
    http mimetype为multipart/x-mixed-replace报文
    Realtek 8192cu 支持 Android Hotspot 软ap
    http协议详解
    Android 在一个程序中启动另一个程序(包名,或者类名)
    linux定时器
    进程与线程的一个简单解释(转)
  • 原文地址:https://www.cnblogs.com/lalalagq/p/10259843.html
Copyright © 2020-2023  润新知