React-Native使用Codepush热更新
在开始之前,首先了解一下RN的热更新原理
开始:
首先,在全局安装appcenter
powershell
npm install -g appcenter-cli
下面对appcenter进行设置
1.登陆
appcenter是微软的,所以我们需要登陆使用,在终端中输入登录命令appcenter login
,会自动打开浏览器,可以选择自己喜欢的方式登陆,登陆后会在网页上显token
,点击复制复制下来,关闭浏览器,粘贴到终端中,回车。
2.配置命令
- 查看配置:
appcenter profile list
- 退出登录:
appcenter logout
- 查看所有的登录token:
appcenter tokens list
- 删除一个token:
appcenter tokens delete <machineName>
3.appcenter相关操作
以下操作均可在网页版appcenter可视化进行,此处仅说明终端部分
为iOS和安卓分别创建App
**** 备注*:将ownerName替换成你在Appcenter的用户名 ****
针对不同系统分别执行下面的命令
shell
appcenter apps create -d <appDisplayName> -o <operatingSystem> -p <platform>
例如针对iOS和安卓分别执行如下命令
shell
appcenter apps create -d RNDemoAndroid -o Android -p React-Native
appcenter apps create -d RNDemoiOS -o iOS -p React-Native
在Appcenter创建完App之后需要针对每个App创建Staging和Production 环境对应的Key
shell
appcenter codepush deployment add -a <ownerName>/RNDemoiOS Staging
appcenter codepush deployment add -a <ownerName>/RNDemoiOS Production
例如我创建了一个名为TimeTable的安卓应用,则我的终端显示如图:(使用appcenter apps list
查看应用列表)
然后使用appcenter codepush deployment list -k -a <username>/myapp-android
查看对应应用的deployment key
到此为止,所有的配置已经结束,接下来就是进入项目中进行
然后进入项目中进行
React-native项目安装Codepush
cd <project name>
进入项目目录,然后执行命令:
powershell
npm install --save react-native-code-push
react-native项目中安卓部分修改
1.修改android/settings.gradle,添加如下代码
js
include ':app', ':react-native-code-push'
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')
2.修改android/app/build.gradle,添加如下代码
js
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"
3.修改MainApplication.java文件
在文件头部引入codepush类,并override getJSBundleFile()
,整体代码如下
java
// 1. Import the plugin class.
import com.microsoft.codepush.react.CodePush;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
...
// 2. Override the getJSBundleFile method to let
// the CodePush runtime determine where to get the JS
// bundle location from on each app start
@Override
protected String getJSBundleFile() {
return CodePush.getJSBundleFile();
}
};
}
4.修改android/app/build.gradle
,在buildTypes代码块中添加如下代码
将<INSERT_STAGING_KEY>替换成你在codepush中的deploymentKey
js
buildTypes {
debug {
signingConfig signingConfigs.debug
ndk {
abiFilters reactNativeArchitectures()
}
// Note: CodePush updates shouldn't be tested in Debug mode as they're overriden by the RN packager. However, because CodePush checks for updates in all modes, we must supply a key.
resValue "string", "CodePushDeploymentKey", '""'
}
//**************************添加代码start***************************************
releaseStaging {
// Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android.
signingConfig signingConfigs.debug
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
resValue "string", "CodePushDeploymentKey", '"<INSERT_STAGING_KEY>"'
matchingFallbacks = ["release"]
}
//**************************添加代码end***************************************
release {
// Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android.
signingConfig signingConfigs.debug
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
resValue "string", "CodePushDeploymentKey", '"<INSERT_STAGING_KEY>"'
}
}
5.js/ts代码
因为是demo项目,我直接更改了本身的app.js
代码,实际开发中视情况而定
js
// App.js
import React from 'react';
import {
SafeAreaView,
ScrollView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
Button
} from 'react-native';
import packageInfo from './package.json'
import CodePush from 'react-native-code-push';
import {
Colors,
Header,
} from 'react-native/Libraries/NewAppScreen';
/* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
* LTI update could not be added via codemod */
const Section = ({children, title}) => {
const isDarkMode = useColorScheme() === 'dark';
return (
<View style={styles.sectionContainer}>
<Text
style={[
styles.sectionTitle,
{
color: isDarkMode ? Colors.white : Colors.black,
},
]}>
{title}
</Text>
<Text
style={[
styles.sectionDescription,
{
color: isDarkMode ? Colors.light : Colors.dark,
},
]}>
{children}
</Text>
</View>
);
};
const App = () => {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
//检查更新方法
const checkForUpdate = () => {
CodePush.sync({
installMode: CodePush.InstallMode.IMMEDIATE,
},(status)=>{
switch (status) {
case CodePush.SyncStatus.UP_TO_DATE:{
alert("当前已经是最新版本")
}
break;
case CodePush.SyncStatus.UPDATE_INSTALLED:{
alert("最新版本已安装")
}
break;
default:
break
}
console.log(status)
},()=>{
});
};
//清除更新
const clear = () => {
CodePush.clearUpdates();
};
var name = packageInfo.name;
var version = packageInfo.version;
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={backgroundStyle}>
<Header />
<View
style={{
backgroundColor: isDarkMode ? Colors.black : Colors.white,
}}>
<Section title="项目名称">
<Text style={styles.highlight}>{name}</Text>
</Section>
<Section title="版本号">
<Text style={styles.highlight}>{version}</Text>
</Section>
<Section title="Version Info">
<Button title='检查更新' onPress={checkForUpdate}/>
<Button title='清除更新' onPress={clear}/>
</Section>
</View>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
},
highlight: {
fontWeight: '700',
},
});
export default App;
最后打包项目
我更改了package.json中的版本号,然后打包上传了版本。
在终端中执行命令appcenter codepush release-react -a <username>/appname
上传版本
使用appcenter codepush deployment list -a <username>/appname
可以看到当前用户更新情况,如图: