美文网首页
react-native-code-push热更新流程(Andr

react-native-code-push热更新流程(Andr

作者: 風隨風去 | 来源:发表于2019-02-13 19:11 被阅读0次

    安装与注册CodePush

    安装 CodePush CLI

    在终端输入如下:

     npm install -g code-push-cli
     code-push -v //查看版本 
    

    创建一个CodePush 账号

     code-push register//注册
     code-push login//登录
    

    在终端输入code-push register,会打开注册页面让你选择授权账号。授权通过之后,CodePush会告诉你“access key”,复制此key到终端即可完成注册。 https://appcenter.ms/

    集成CodePush SDK

    第一步:在项目中安装 react-native-code-push插件,终端进入你的项目根目录然后运行

     npm install react-native-code-push --save
    

    Android集成SDK

    第二步: 运行 npm link react-native-code-push。这条命令将会自动帮我们在anroid文件中添加好设置

    第三步: 在 android/app/build.gradle文件里面添如下代码:

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

    如果第二步没有成功,则手动配置

    ... 
    dependencies { 
    ...  
      implementation project(':react-native-code-push') 
    ... 
    } 
    ...
    

    在/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')
    

    在/android/app/src/com/.../.../MainApplication.java中添加如下代码:

     ...
     import com.microsoft.codepush.react.CodePush; 
     ...
     @Override
     protected String getJSBundleFile() { 
         return CodePush.getJSBundleFile(); 
    }
    ... 
    @Override 
    protected List<ReactPackage> getPackages() { 
      return Arrays.<ReactPackage>asList( 
        ...               
        new CodePush(CODEPUSH_KEY_STAGING, getApplicationContext(), BuildConfig.DEBUG) );
    }  
    ...
    

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

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

    public class MainApplication extends MultiDexApplication implements ReactApplication { 
      private final String CODEPUSH_KEY_PRODUCTIO = "your Production key";
      private final String CODEPUSH_KEY_STAGING = "your Staging key";
      private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
      ...     
        @Override 
         protected String getJSBundleFile() {  
           return CodePush.getJSBundleFile(); 
         } 
         @Override   
         public boolean getUseDeveloperSupport() {  
            return BuildConfig.DEBUG; 
         } 
        @Override    
        protected List<ReactPackage> getPackages() {  
           return Arrays.<ReactPackage>asList(    
             new CodePush(CODEPUSH_KEY_STAGING, getApplicationContext(), BuildConfig.DEBUG)  
           ); 
        } 
        ...
      };  
      @Override 
      public ReactNativeHost getReactNativeHost() {  
        return mReactNativeHost; 
      } 
    }
    

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

    android{ 
      ...
      defaultConfig{ 
         versionName "0.0.1" 
      }
      ...
    }
    

    使用CodePush

    codepush常用命令

    • 安装 CodePush CLI: npm install -g code-push-cli
    • 创建一个CodePush 账号: code-push register
    • 登陆:code-push login
    • 注销:code-push loout
    • 列出登陆的token: code-push access-key ls
    • 删除某个 access-key: code-push access-key rm <accessKye>
    • 创建一个app: code-push app add <appName> <os> <platform> 其中os为ios或android,platform为react-native
    • 在账号里移除一个 app:code-push app remove 或者 rm
    • 重命名一个存在 app: code-push app rename
    • 列出账号下面的所有 app: code-push app list 或则 ls
    • 把app的所有权转移到另外一个账号:code-push app transfer
    • 直接使用下面的命令查到对应应用的deployment key: code-push deployment ls <appName> -k
    • 部署:code-push deployment add <appName>
    • 重命名:code-push deployment rename <appName>
    • 删除部署:code-push deployment rm <appName>
    • 列出应用的部署情况:code-push deployment ls <appName>
    • 查看部署的key:code-push deployment ls <appName> -k
    • 查看历史版本:code-push deployment history <appName> <deploymentNmae> (Production 或者 Staging)
    • 发布热更新:code-push release-react <appName> <os> --description "1.描述"
    • 发布热更新:code-push release-react <appName> <os> -t 版本 -d 环境 --des 描述 -m true (强制更新)
    • 删除部署:code-push deployment rm <appName> <deploymentNmae> deploymentNmae(Production 或者 Staging)
    • 清除历史部署记录 code-push deployment clear <appName> Production or Staging
    • 回滚 code-push rollback <appName> Production --targetRelease v4(codepush服务部署的版本号)

    更新方式

    1、首先最简单的一种就是 这种无声的热更新,也就是说热更新不会给用户任何提示,都在默默的进行更新,用户完全体会不到整个过程

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

    2、第二种 也是无声更新,比第一种情况多了一种就是热更新每次会在后台返回前台的时候进行热更新。这里可以看到几个参数,

    checkFrequency有三种状态如下

    ON_APP_START: //在组件初始化的时候进行热更新

    ON_APP_RESUME://在每次app从后台回到前台的时候进行热更新

    MANUAL://不进行热更新,需要自己手动配置

    InstallMode 有如下几种状态

    IMMEDIATE :// 安装热更新,并且重启app

    ON_NEXT_RESTART: //下次启动的时候启动热更新

    ON_NEXT_RESUME //从后台回到前台的时候启动

    ON_NEXT_SUSPEND: 在后台的时候进行热更新

    class MyApp extends Component<{}> {}
    
    MyApp= CodePush({ 
    checkFrequency: codePush.CheckFrequency.ON_APP_RESUME,
    installMode: codePush.InstallMode.ON_NEXT_RESUME
    })(MyApp);
    
    export default MyApp;
    

    updateDialog 当为true 是,可以在更新的时候提示用户需要更新

    ** 关于部署秘钥的检测更新(已配置可忽略deploymentKey)和更新包下载进度提示modal

    import React, {Component} from 'react';
    import { Platform,Modal,View,Text } from 'react-native';
    import {Provider} from 'mobx-react/native';
    import stores from './store/';
    import Routers from './routers/';
    import CodePush from 'react-native-code-push';
    
    const Dimensions = require('Dimensions');
    const screenW = Dimensions.get('window').width;
    
    const CODEPUSH_KEY = {
      Android:{
        Staging:'YOUR_ANDROID_STAGING_KEY',
        Production:'YOUR_ANDROID_PRODUCTION_KEY'
      },
      Ios:{
        Staging:'YOUR_IOS_STAGING_KEY',
        Production:'YOUR_IOS_PRODUCTION_KEY'
      }
    }
    
    class App extends Component<Props> {
      state = {
        modalVisible: false,
        downloadProgess:0
      }
      componentDidMount(){
        CodePush.sync({
          deploymentKey:Platform.OS=='android'?CODEPUSH_KEY.Android.Production:CODEPUSH_KEY.Ios.Production,
          installMode: CodePush.InstallMode.IMMEDIATE,
          updateDialog : {
            //是否显示更新描述
            appendReleaseDescription : true ,
            //更新描述的前缀。 默认为"Description"
            descriptionPrefix : "\n\n更新說明:\n" ,
            //强制更新按钮文字,默认为continue
            mandatoryContinueButtonLabel : "立即更新" ,
            //强制更新时的信息. 默认为"An update is available that must be installed."
            mandatoryUpdateMessage : "發現重要更新,必須更新後才能使用!" ,
            //非强制更新时,按钮文字,默认为"ignore"
            optionalIgnoreButtonLabel : '稍後' ,
            //非强制更新时,确认按钮文字. 默认为"Install"
            optionalInstallButtonLabel : '立即更新' ,
            //非强制更新时,检查到更新的消息文本
            optionalUpdateMessage : '發現新版本,是否更新?' ,
            //Alert窗口的标题
            title : '更新提示'
          }
        },(status) => {
          switch(status) {
              case CodePush.SyncStatus.CHECKING_FOR_UPDATE:
                // console.warn("Checking for updates.");
              break;
              case CodePush.SyncStatus.DOWNLOADING_PACKAGE:
                this.setState({ modalVisible:true })
                // console.warn("Downloading package.");
              break;
              case CodePush.SyncStatus.INSTALLING_UPDATE:
                this.setState({ modalVisible:false })
                // console.warn("Installing update.");
              break;
              case CodePush.SyncStatus.UP_TO_DATE:
                this.setState({ modalVisible:false });
                // console.warn("Installing uptodate.");
              break;
              case CodePush.SyncStatus.UPDATE_INSTALLED:
                this.setState({ modalVisible:false });
                // console.warn("Update installed.");
              break;
            }
          },(progress) => {
            let receivedBytes = progress.receivedBytes;
            let totalBytes = progress.totalBytes;
            let downloadProgess = (receivedBytes/totalBytes).toFixed(2) ;
            this.setState({ downloadProgess:downloadProgess });
            // console.warn(progress.receivedBytes + " of " + progress.totalBytes + " received.");
          }
        )
      }
      render() {
        let { modalVisible,downloadProgess } = this.state;
        let percentProgess = String(parseInt(downloadProgess*100)) + '%';
        return <View style={{flex:1}}>
          <Provider {...stores}><Routers/></Provider>
          <Modal
            visible={modalVisible}
            animated={'slide'}
            transparent={true}
            onRequestClose={()=>this.setState({ modalVisible:false })}
          >
            <View style={{flex:1,backgroundColor:'rgba(0,0,0,0.4)',flexDirection:'row',alignItems:'center',justifyContent:'center'}}>
              <View style={{alignItems:'center',justifyContent:'center'}}>
                <View style={{flexDirection:'row',alignItems:'center',justifyContent:'center'}}>
                  <View style={{width:screenW*0.6,height:20,borderRadius:10,backgroundColor:'#e5e5e5'}}>
                    <View style={{width:screenW*0.6*downloadProgess,height:20,borderRadius:10,backgroundColor:'#ff6952'}}></View>
                  </View>
                  <Text style={{color:'#fff',marginLeft:10,fontSize:14}}>{percentProgess}</Text>
                </View>
                <Text style={{color:'#fff',marginTop:12}}>{downloadProgess<1?'正在下載更新資源包,請稍候。。。':'下載完成,應用即將重啟'}</Text>
              </View>
            </View>
          </Modal>
        </View> ;
      }
    }
    
    App=CodePush({checkFrequency: CodePush.CheckFrequency.ON_APP_START})(App);
    
    export default App;
    
    

    发布更新

    code-push release-react <appName> <os> --description "1.描述"

    1.code-push release-react MyApp-ios ios --description "1.测试热更新"
    2.code-push release-react MyApp-android android --description "1.测试热更新"
    

    以下发布更新需手动打包:
    code-push release <应用名称> <Bundles所在目录> <对应的应用版本> --deploymentName: 更新环境 --description: 更新描述 --mandatory: 是否强制更新

    react-native bundle --platform ios --entry-file index.js --bundle-output ./bundles/index.ios.bundle --dev false
    code-push release MyApp-ios ./bundles/index.ios.bundle 1.0.0 --description "1.测试热更新" --mandatory false
    

    相关文章

      网友评论

          本文标题:react-native-code-push热更新流程(Andr

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