这个搞得也是不容易,因为RN的版本升到0.6x后,使用了AndroidX,搜到的网贴中提到的好些包,还是旧的,得替换成AndroidX的。我使用的环境参数:
"react-native": "0.61.5"
buildToolsVersion = "28.0.3"
minSdkVersion = 16
compileSdkVersion = 28
targetSdkVersion = 28
classpath("com.android.tools.build:gradle:3.4.2")
首先安装react-native-app-upgrade和react-native-fs依赖,均为最新版本。前者安装后,在node_modules/react-native-app-upgrade下没有实质的内容,或许不需要了;因为搞得比较辛苦,也不想删了,随它去吧!
接着在MainApplication.java所在包下新建一个子包,如rnupgrade,然后拷入一共是9个文件。NotificationCompat.Builder、FileProvider至少在DownloadService.java中有引入,其对应的androix包为:
import androidx.core.app.NotificationCompat.Builder;
import androidx.core.content.FileProvider;
注意:需要在MainApplication中手动添加rnupgrade包中的UpgradePackage。
必不可少的是修改AndroidManifest.xml文件,权限部分包括:
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
在<application>元素里包括:
// 添加fileProvider配置代码
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.updateFileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/update_file_provider" />
</provider>
// 添加Service代码
<service
android:name=".rnupgrade.DownloadService"
android:exported="true" />
相应地,在res/xml下添加update_file_provider.xml文件,内容为:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-cache-path
name="update_external_cache"
path="." />
<cache-path
name="update_cache"
path="." />
</paths>
在res/values/strings.xml里添加一条配置,它将出现在通知栏的下载进度提示上:
<string name="android_auto_update_download_progress">正在下载: %1$d%%</string>
到此为止,在原生android中处理的内容就结束了。下面是js部分,包括1-如何发现新版本、2-授权升级、3-执行下载并更新、4-显示下载进度这四部分内容。
- 如何发现新版本
这个完全是自己定义,生产环境当然是要请求接口来获取最新版本号与当前app的版本号比较来决定是否有了新版本。调试时我简单地用DEV变量,这样更新为非调试包后,自然就不会提示了:
const hasNewVersion = __DEV__; // todo: 请求接口来判断
if (hasNewVersion) {
Alert.alert('确认', '发现新版本,立即升级?', [
{text: '取消', style: 'cancel'},
{
text: '是的', onPress: () => {
this._upgrade();
},
},
], {cancelable: false});
}
注意:为了调试包能直接升级为非调试包,需要让debug和release签名一样,这在WebStorm向导创建的React-Native项目中默认就是这样的。
授权升级
AndroidX对某些权限需要代码显式处理授权。自升级要授的权限是PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,而REQUEST_INSTALL_PACKAGES不需要(也不在RN的PermissionsAndroid.PERMISSIONS之中)。执行下载并更新
这只需要一句代码:
NativeModules.upgrade.upgrade("http://<IP or DOMAIN>/path.../app-release.apk");
第一个upgrade应该是对应了UpgradeModule.java中getName()方法的返回值,第二个upgrade应该是模块的内置方法名。
- 显示下载进度:
在上面一句代码下,紧接着调用如下代码,即可得到进度数值:0-100。通常设置到某个state,即可渲染进度条:
DeviceEventEmitter.addListener('LOAD_PROGRESS', (percent) => {
this.setState({ upgrading: percent !== 100, percent });
});
如有兴趣可QQ联系我:290016446。
参考了:
https://www.jianshu.com/p/c487c59df7eb
https://www.jianshu.com/p/bdc230f8e1eb