ReactNative实现codePush热修复

React Native中android集成code-push框架实现热修复

1.本地电脑安装code-push

       电脑cmd命令行中安装codepush本地启动器:npm install -g code-push-cli
安装完成之后运行code-push register会在浏览器打开网址进行注册 可以用github账号进行登录 登陆之后给一个key复制下来粘贴在cmd中,然后回车完成注册
注册
登陆成功
       然后终端输入code-push login进行登陆,登陆成功后,你的session文件将会写在 /Users/你的用户名/.code-push.config。
相关命令:
       code-push login 登陆
       code-push loout 注销
       code-push access-key ls 列出登陆的token
       code-push access-key rm 删除某个 access-key

2.在CodePush服务器注册app

       为了让CodePush服务器知道你的app,我们需要向它注册app: 在终端输入code-push app add 即可完成注册。
       例如:code-push app add JiuYue
       注册完成之后会返回一套deployment key,该key在后面步骤中会用
deployment key
注意:如果你的应用分为Android和iOS版,那么在向CodePush注册应用的时候需要注册两个App获取两套deployment key,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的所有权转移到另外一个账号

3.android端集成CodePush

第一步:在项目中安装 react-native-code-push插件,终端进入你的项目根目录然后运行
       npm install --save react-native-code-push
第二步:进行link
       react-native link react-native-code-push(这一块有些博客比较旧,是使用的rnpm,较新的版本没有必要)
       在终端运行此命令之后,终端会提示让你输入deployment key,这个地方可以输入也可以直接回车跳过。
       第一种情况:如果输入自己前一步返回的任意一个key之后会自动在values中给配置,在MainApplication中进行配置,输入的key也需要和后面在js中检测更新时给的key保持一致。一般建议输入production的key。
       link之后查看/android/app/build.gradle中是否有apply from: “…/…/node_modules/react-native-code-push/android/codepush.gradle” ,没有就添加
       然后在/android/settings.gradle中查看是否有如下代码,没有就添加:

include ':react-native-code-push'
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')

       第二种情况,在link时没有输入自己选择的key,可以自己在build.gradle中进行打包时的配置,具体步骤如下:
link完成之后在/android/app/build.gradle中添加代码:

buildTypes {

        debug {
	···
            buildConfigField "String", "CODEPUSH_KEY", '"你自己的Staging  Deployment Key "'
        ···
        }

        release {
            ···
            buildConfigField "String", "CODEPUSH_KEY", '"你自己的Production Deployment Key "'
            ···
        }

    }

       一般来说,release中是Production的Deployment Key,属于正式环境下的key。
       如果要区分两种key的关系,查看博客:react-native-code-push进阶篇
       在MainApplication中的配置:
       新增这个重写的方法并且别忘记导包:

  import android.support.annotation.NonNull;
  
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {

	@NonNull
    @Override
   	protected String getJSBundleFile() {
    	  return CodePush.getJSBundleFile();
   }


}

在MainApplication中配置的new CodePush最终形态

 @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          ···
            new CodePush(BuildConfig.CODEPUSH_KEY, getApplicationContext(), BuildConfig.DEBUG),
          ···
      );
    }

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

4.在js中进行更新检测配置:

//尽量在主界面的入口处进行调用
	componentDidMount() {
		this.checkCodePushVersion()
	}
//code push热修复接入口
    checkCodePushVersion() {
        codePush.sync({
                updateDialog: {
                    appendReleaseDescription: true,          //true表示显示更新信息,如果为false就不会提示用户直接下载
                    descriptionPrefix: '\n更新内容:\n',
                    title: '有新的更新包',
                    mandatoryUpdateMessage: '',
                    mandatoryContinueButtonLabel: '更新',
                },
                mandatoryInstallMode: codePush.InstallMode.ON_NEXT_RESTART,     //更新模式
                deploymentKey: DEPLOYMENTKEY,     //你自己配置的key,打包时使用到的DEPLOYMENTKEY
            },
            this.codePushStatusDidChange.bind(this),  //状态监听
            this.codePushDownloadDidProgress.bind(this));   //下载进度监听
    }
//code-push的状态监听
 	codePushStatusDidChange(status) {
        switch (status) {
            case codePush.SyncStatus.CHECKING_FOR_UPDATE:
                console.log("Checking for updates.");
                break;
            case codePush.SyncStatus.DOWNLOADING_PACKAGE:
                console.log("Downloading package.");
                break;
            case codePush.SyncStatus.INSTALLING_UPDATE:
                ToastAndroid.showWithGravity("下载完成,下次进入将会自动更新", ToastAndroid.SHORT, ToastAndroid.CENTER)
                break;
            case codePush.SyncStatus.UP_TO_DATE:
                console.log("Installing update.");
                break;
            case codePush.SyncStatus.UPDATE_INSTALLED:
                console.log("Update installed.");
                break;
        }
    }
    
	//code-push的下载进度监听
    codePushDownloadDidProgress(progress) {
        console.log(progress.receivedBytes + " of " + progress.totalBytes + " received.");
    }

(1)sync方法,提供了如下属性以允许你定制sync方法的默认行为
       deploymentKey (String): 部署key,指定你要查询更新的部署秘钥,你可以通过设置该属性来动态查询不同部署key下的更新。
       installMode (codePush.InstallMode): 安装模式,用在向CodePush推送更新时没有设置强制更新(mandatory为true)的情况下,默认codePush.InstallMode.ON_NEXT_RESTART即下一次启动的时候安装。
       mandatoryInstallMode (codePush.InstallMode):强制更新,默认codePush.InstallMode.IMMEDIATE。
       minimumBackgroundDuration (Number):该属性用于指定app处于后台多少秒才进行重启已完成更新。默认为0。 该属性只在installMode为InstallMode.ON_NEXT_RESUME情况下有效。
       updateDialog (UpdateDialogOptions) :可选的,更新的对话框,默认是null,包含以下属性
       appendReleaseDescription (Boolean) - 是否显示更新description,默认false
       descriptionPrefix (String) - 更新说明的前缀。 默认是” Description: “
       mandatoryContinueButtonLabel (String) - 强制更新的按钮文字. 默认 to “Continue”.
       mandatoryUpdateMessage (String) - 强制更新时,更新通知. Defaults to “An update is available that must be installed.”.
       optionalIgnoreButtonLabel (String) - 非强制更新时,取消按钮文字. Defaults to “Ignore”.
       optionalInstallButtonLabel (String) - 非强制更新时,确认文字. Defaults to “Install”.
       optionalUpdateMessage (String) - 非强制更新时,更新通知. Defaults to “An update is available. Would you like to install it?”.
       title (String) - 要显示的更新通知的标题. Defaults to “Update available”.
(2)需要注意的是,sync方法需要在每次启动是都调用,不然会出现版本的回退。

5.版本发布

准备工作:在项目根目录下创建一个文件夹bundles
然后在项目根目录下进行命令行输入
(1)打包
react-native bundle --entry-file index.js --bundle-output ./bundles/index.android.bundle --platform android --assets-dest ./bundles --dev false
(2)打包完成之后将打包的bundes更新到codepush服务器
code-push release 你的项目名 ./bundles 1.0.0 --deploymentName Production --description “修改电子书评价” --mandatory true
参数介绍:
code-push release <应用名称> <Bundles所在目录> <对应的应用版本> --deploymentName: 更新环境 --description: 更新描述 --mandatory: 是否强制更新
注意:(1)这里的版本号是你现在线上的apk版本号,而不是你打包时的版本号,很多人在这一步做错,就是因为在生成apk时版本号是1.0.0,但是打包bundles时人为把版本号升级到1.0.1,然后命令行输入的也是
code-push release 你的项目名 ./bundles 1.0.1 --deploymentName Production --description “修改电子书评价” --mandatory true
这个是错误的做法,如果这样做的话,codepush会去找1.0.1版本号的apk去提示更新,这样就会出现你生成的1.0.0的包接收不到升级提示或者会报有更新,但是不是针对你的apk版本。所以需要注入你生成的apk的版本是多少,这里对应的版本就是多少,不管你对这个版本进行了多少次的codepush,版本号是不变的。jsbundles只是打包js文件,不会去打包android文件夹下的内容。
       (2)很多博客上的打包命令都是错误的,只能打包出js文件,忽略了图片数据,这样你在更新之后会出现本地的图标无法显示的问题,需要注意这个坑。

6.其他:

使用code-push app ls查看是否添加成功?
       默认会创建两个部署(deployment)环境:Staging和Production,可以通过code-push deployment ls MyAppIOS -k来查看当前App所有的部署,-k是用来查看部署的key,这个key是要方法原生项目中去的

已经发布到Production的更新如果撤销?
       如果发生了我上面提到的发布出去的更新有bug或者重大崩溃,不想让更多的用户检测到此更新怎么办?这时你可以马上登录code-push官网https://microsoft.github.io/code-push/ ,然后登录进入到App Center,选择你对应的App, 选择Distribute-> Code-Push, 选择Production,点击你想要撤销的版本,有个设置的按钮,将Enabled 关掉,这样用户就检测不到你此版本了。

热更新是更新的那些内容?
       热更新只是更新的js代码,并不能更新原生中的更改,所以如果你在原生中改了什么东西或者是更新了一些RN的三方库都需要重新打原生包发布到AppStore或者是android应用市场中去,而不能通过热更新来实现

参考博客:
       React Native应用部署/热更新-CodePush最新集成总结
       react-native-code-push进阶及实践小结
       react-native-code-push进阶篇

猜你喜欢

转载自blog.csdn.net/m0_37194191/article/details/84103370