标签:running DDM 自定义 \n HERE back ble hang ref
React Native应用部署/热更新-CodePush最新集成总结
本文出自《React Native学习笔记》系列文章。
了解更多,可以关注我的GitHub和加入:
React Native学习交流群
更新说明:
此次博文更新适配了最新版的CodePush v1.17.0;添加了iOS的集成方式与调试技巧;添加了更为简洁的CodePush发布更新的方式以及进行了一些其他的优化。
React Native的出现为移动开发领域带来了两大革命性的创新:
本文将向大家分享React Natvie应用部署/动态更新方面的内容。
React Native支持大家用React Native技术开发APP,并打包生成一个APP。在动态更新方面React Native只是提供了动态更新的基础,对将应用部署到哪里,如何进行动态更新并没有支持的那么完善。好在微软开发了CodePush,填补React Native 应用在动态更新方面的空白。CodePush 是微软提供的一套用于热更新 React Native 和 Cordova 应用的服务。下面将向大家分享如何使用CodePush实时更新你的应用,后期会分享不采用CodePush,如何自己去实现React Native应用热更新。
CodePush 是微软提供的一套用于热更新 React Native 和 Cordova 应用的服务。
CodePush 是提供给 React Native 和 Cordova 开发者直接部署移动应用更新给用户设备的云服务。CodePush 作为一个中央仓库,开发者可以推送更新 (JS, HTML, CSS and images),应用可以从客户端 SDK 里面查询更新。CodePush 可以让应用有更多的可确定性,也可以让你直接接触用户群。在修复一些小问题和添加新特性的时候,不需要经过二进制打包,可以直接推送代码进行实时更新。
CodePush 可以进行实时的推送代码更新:
CodePush开源了react-native版本,react-native-code-push托管在GitHub上。
使用CodePush之前首先要安装CodePush客户端。本文以OSX 10.11.5作为平台进行演示。
管理 CodePush 账号需要通过 NodeJS-based CLI。
只需要在终端输入 npm install -g code-push-cli
,就可以安装了。
安装完毕后,输入 code-push -v
查看版本,如看到版本代表成功。
![安装 CodePush CLI成功](https://raw.githubusercontent.com/crazycodeboy/RNStudyNotes/master/React%20Native应用部署、热更新-CodePush最新集成总结/images/安装 CodePush CLI成功.png)
目前我的版本是 1.12.1-beta
PS. npm
为NodeJS的包管理器,如果你没安装NodeJS请先安装。
在终端输入code-push register
,会打开如下注册页面让你选择授权账号。
code-push login
进行登陆,登陆成功后,你的session文件将会写在 /Users/你的用户名/.code-push.config。
PS.相关命令
code-push login
登陆code-push loout
注销code-push access-key ls
列出登陆的tokencode-push access-key rm <accessKye>
删除某个 access-key为了让CodePush服务器知道你的app,我们需要向它注册app: 在终端输入code-push app add <appName>
即可完成注册。
注册完成之后会返回一套deployment key,该key在后面步骤中会用到。
心得:如果你的应用分为Android和iOS版,那么在向CodePush注册应用的时候需要注册两个App获取两套deployment key,如:
PS.相关命令
code-push app add
在账号里面添加一个新的appcode-push app remove
或者 rm 在账号里移除一个appcode-push app rename
重命名一个存在appcode-push app list
或则 ls 列出账号下面的所有appcode-push app transfer
把app的所有权转移到另外一个账号下面我们通过如下步骤在Android项目中集成CodePush。
第一步:在项目中安装 react-native-code-push插件,终端进入你的项目根目录然后运行npm install --save react-native-code-push
第二步:在Android project中安装插件。
CodePush提供了两种方式:RNPM 和 Manual,本次演示所使用的是RNPM。
运行npm i -g rnpm
,来安装RNPM。
在React Native v0.27及以后版本RNPM已经被集成到了 React Native CL中,就不需要再进行安装了。
第三步: 运行 rnpm link react-native-code-push
。这条命令将会自动帮我们在anroid文件中添加好设置。
在终端运行此命令之后,终端会提示让你输入deployment key,这是你只需将你的deployment Staging key输入进去即可,如果不输入则直接单击enter跳过即可。
第四步: 在 android/app/build.gradle文件里面添如下代码:
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"
include ‘:react-native-code-push‘
project(‘:react-native-code-push‘).projectDir = new File(rootProject.projectDir, ‘../node_modules/react-native-code-push/android/app‘)
第五步: 运行 code-push deployment -k ls <appName>
获取 部署秘钥。默认的部署名是 staging,所以 部署秘钥(deployment key ) 就是 staging。
第六步: 添加配置。当APP启动时我们需要让app向CodePush咨询JS bundle的所在位置,这样CodePush就可以控制版本。更新 MainApplication.java文件:
public class MainApplication extends Application implements ReactApplication {
}
关于deployment-key的设置
在上述代码中我们在创建CodePush实例的时候需要设置一个deployment-key,因为deployment-key分生产环境与测试环境两种,所以建议大家在build.gradle中进行设置。在build.gradle中的设置方法如下:
打开android/app/build.gradle文件,找到android { buildTypes {} }
然后添加如下代码即可:
android {
}
心得:另外,我们也可以将deployment-key存放在local.properties中:
如图:
然后在就可以在android/app/build.gradle可以通过下面方式来引用它了:
Properties properties = new Properties()
properties.load(project.rootProject.file(‘local.properties‘).newDataInputStream())
android {
releaseStaging {
release {
}
在android/app/build.gradle设置好deployment-key之后呢,我们就可以这样使用了:
protected List<ReactPackage> getPackages() {
}
第七步:修改versionName。
在 android/app/build.gradle中有个 android.defaultConfig.versionName属性,我们需要把 应用版本改成 1.0.0(默认是1.0,但是codepush需要三位数)。
至此Code Push for Android的SDK已经集成完成。
CodePush官方提供RNPM、CocoaPods与手动三种在iOS项目中集成CodePush的方式,接下来我就以RNPM的方式来讲解一下如何在iOS项目中集成CodePush。
第一步:在项目中安装react-native-code-push插件,终端进入你的项目根目录然后运行
npm install --save react-native-code-push
第二步: 运行 rnpm link react-native-code-push
。这条命令将会自动帮我们在ios中添加好设置。
在终端运行此命令之后,终端会提示让你输入deployment key,这是你只需将你的deployment Staging key输入进去即可,如果不输入则直接单击enter跳过即可。
关于deployment-key的设置
在我们想CodePush注册App的时候,CodePush会给我们两个deployment-key分别是在生产环境与测试环境时使用的,我们可以通过如下步骤来设置deployment-key。
1.用Xcode 打开项目 ? Xcode的项目导航视图中的PROJECT
下选择你的项目 ? 选择Info页签 ? 在Configurations
节点下单击 + 按钮 ? 选择Duplicate "Release
? 输入Staging(名称可以自定义);
2.然后选择Build Settings
页签 ? 单击 + 按钮然后选择添加User-Defined Setting
3.然后输入CODEPUSH_KEY(名称可以自定义)
提示:你可以通过
code-push deployment ls <APP_NAME> -k
命令来查看deployment key。
4.打开 Info.plist文件,在CodePushDeploymentKey列的Value中输入$(CODEPUSH_KEY)
到目前为止,iOS的设置已经完成了,和在Android上的集成相比是不是简单了很多呢。
在使用CodePush更新你的应用之前需要,先配置一下更新控制策略,即:
最简单的方式是在根component中进行上述策略控制。
import codePush from ‘react-native-code-push‘
componentDidMount
中调用 sync
方法,后台请求更新codePush.sync()
如果可以进行更新,CodePush会在后台静默地将更新下载到本地,等待APP下一次启动的时候应用更新,以确保用户看到的是最新版本。
如果更新是强制性的,更新文件下载好之后会立即进行更新。
如果你期望更及时的获得更新,可以在每次APP从后台进入前台的时候去主动的检查更新:
在应用的根component的componentDidMount
中添加如下代码:
AppState.addEventListener("change", (newState) => {
});
CodePush支持两种发布更新的方式,一种是通过code-push release-react
简化方式,另外一种是通过code-push release
的复杂方式。
第一种方式:通过
code-push release-react
发布更新
这种方式将打包与发布两个命令合二为一,可以说大大简化了我们的操作流程,建议大家多使用这种方式来发布更新。
命令格式:
code-push release-react <appName> <platform>
eg:
再来个更高级的:
code-push release-react MyApp-iOS ios --t 1.0.0 --dev false --d Production --des "1.优化操作流程" --m true
其中参数--t为二进制(.ipa与apk)安装包的的版本;--dev为是否启用开发者模式(默认为false);--d是要发布更新的环境分Production与Staging(默认为Staging);--des为更新说明;--m 是强制更新。
关于code-push release-react
更多可选的参数,可以在终端输入code-push release-react
进行查看。
另外,我们可以通过code-push deployment ls <appName>
来查看发布详情与此次更新的安装情况。
第二中方式:通过
code-push release
发布更新
code-push release
发布更新呢我们首先需要将js与图片资源进行打包成 bundle。
发布更新之前,需要先把 js打包成 bundle,如:
第一步: 在 工程目录里面新增 bundles文件:mkdir bundles
第二步: 运行命令打包 react-native bundle --platform 平台 --entry-file 启动文件 --bundle-output 打包js输出文件 --assets-dest 资源输出目录 --dev 是否调试
。
eg:react-native bundle --platform android --entry-file index.android.js --bundle-output ./bundles/index.android.bundle --dev false
需要注意的是:
打包bundle结束后,就可以通过CodePush发布更新了。在终端输入code-push release <应用名称> <Bundles所在目录> <对应的应用版本> --deploymentName: 更新环境 --description: 更新描述 --mandatory: 是否强制更新
eg:code-push release GitHubPopular ./bundles/index.android.bundle 1.0.6 --deploymentName Production --description "1.支持文章缓存。" --mandatory true
注意:
所以如果我们要对某一个应用版本进行多次更新,只需要上传与上次不同的bundle/images即可。如:
eg:
对1.0.6的版本进行第一次更新:code-push release GitHubPopular ./bundles/index.android.bundle 1.0.6 --deploymentName Production --description "1.支持文章缓存。" --mandatory true
对1.0.6的版本进行第二次更新:code-push release GitHubPopular ./bundles/index.android.bundle 1.0.6 --deploymentName Production --description "1.新添加收藏功能。" --mandatory true
code-push deployment history <appName> Staging
可以看到Staging版本更新的时间、描述等等属性。code-push release Equipment ./bundles 1.0.1
下面我们启动事先安装好的应用,看有什么反应:
更多部署APP相关命令
如果你用模拟器进行调试CodePush,在默认情况下是无法达到调试效果的,因为在开发环境下装在模拟器上的React Native应用每次启动时都会从NodeJS服务器上获取最新的bundle,所以还没等CodePush从服务器将更新包下载下来时,APP就已经从NodeJS服务器完成了更新。
Android
为规避这个问题在Android可以将开发环境的调试地址改为一个不可用的地址,如下图:
iOS
在iOS中我们需要上文中讲到的生成bundle,将bundle包与相应的图片资源拖到iOS项目中如图:
然后呢,我们需要在AppDelegate.m中进行如下修改:
让React Native通过CodePush去获取bundle包即可。
其实我们可以将这些API分为两类,一类是自动模式,一类是手动模式。
sync
为自动模式,调用此方法CodePush会帮你完成一系列的操作。其它方法都是在手动模式下使用的。
codePush.sync codePush.sync(options: Object, syncStatusChangeCallback: function(syncStatus: Number), downloadProgressCallback: function(progress: DownloadProgress)): Promise<Number>;
通过调用该方法CodePush会帮我们自动完成检查更新,下载,安装等一系列操作。除非我们需要自定义UI表现,不然直接用这个方法就可以了。
sync方法,提供了如下属性以允许你定制sync方法的默认行为
installMode
为InstallMode.ON_NEXT_RESUME
情况下有效。eg:
codePush.sync({
title:‘更新‘,
mandatoryUpdateMessage:‘‘,
mandatoryContinueButtonLabel:‘更新‘,
codePush.allowRestart
codePush.allowRestart(): void;
允许重新启动应用以完成更新。
如果一个CodePush更新将要发生并且需要重启应用(e.g.设置了InstallMode.IMMEDIATE模式),但由于调用了disallowRestart
方法而导致APP无法通过重启来完成更新,
可以调用此方法来解除disallowRestart
限制。
但在如下四种情况下,CodePush将不会立即重启应用:
disallowRestart
被调用,没有新的更新。installMode
为InstallMode.ON_NEXT_RESTART
的情况下。installMode
为InstallMode.ON_NEXT_RESUME
,并且程序一直处于前台,并没有从后台切换到前台的情况下。disallowRestart
被调用,没有再调用restartApp
。codePush.checkForUpdate
codePush.checkForUpdate(deploymentKey: String = null): Promise<RemotePackage>;
向CodePush服务器查询是否有更新。
该方法返回Promise,有如下两种值:
null 没有更新
通常有如下情况导致RemotePackage为null:
A RemotePackage instance
有更新可供下载。
eg:
codePush.checkForUpdate()
.then((update) => {
console.log("The app is up to date!");
});
codePush.disallowRestart
codePush.disallowRestart(): void;
不允许立即重启用于以完成更新。
eg:
class OnboardingProcess extends Component {
componentWillMount() {
// a restart if one was currently pending.
codePush.allowRestart();
}
codePush.getUpdateMetadata codePush.getUpdateMetadata(updateState: UpdateState = UpdateState.RUNNING): Promise<LocalPackage>;
获取当前已安装更新的元数据(描述、安装时间、大小等)。
eg:
// Check if there is currently a CodePush update running, and if
// so, register it with the HockeyApp SDK (https://github.com/slowpath/react-native-hockeyapp)
// so that crash reports will correctly display the JS bundle version the user was running.
codePush.getUpdateMetadata().then((update) => {
});
// Check to see if there is still an update pending.
codePush.getUpdateMetadata(UpdateState.PENDING).then((update) => {
});
codePush.notifyAppReady codePush.notifyAppReady(): Promise<void>;
通知CodePush,一个更新安装好了。当你检查并安装更新,(比如没有使用sync方法去handle的时候),这个方法必须被调用。否则CodePush会认为update失败,并rollback当前版本,在app重启时。
当使用sync
方法时,不需要调用本方法,因为sync
会自动调用。
codePush.restartApp codePush.restartApp(onlyIfUpdateIsPending: Boolean = false): void;
立即重启app。
当以下情况时,这个方式是很有用的:
sync
或 LocalPackage.install
方法时,指定的 install mode
是 ON_NEXT_RESTART
或 ON_NEXT_RESUME时
。 这两种情况都是当app重启或resume
时,更新内容才能被看到。上文已经介绍了CodePush在动态更新方面的一些特性,但CodePush也存在着一些缺点:
参考:
http://microsoft.github.io/code-push/docs/getting-started.html
https://github.com/Microsoft/react-native-code-push
react-native热更新之CodePush详细介绍及使用方法
标签:running DDM 自定义 \n HERE back ble hang ref
原文地址:https://www.cnblogs.com/zhangycun/p/10263205.html