1
0
mirror of https://gitcode.com/gh_mirrors/re/react-native-pushy.git synced 2025-11-23 07:53:38 +08:00
Code Issues Packages Projects Releases Wiki Activity GitHub Gitee

Compare commits

...

8 Commits

Author SHA1 Message Date
sunnylqm
db548d03dd v5.11.0-beta0 2021-01-20 23:15:05 +08:00
sunnylqm
fc82addd75 Check diff and patch existence 2021-01-20 23:05:35 +08:00
sunnylqm
90e7c00cf6 Clean up files if task failed 2021-01-20 18:34:58 +08:00
sunnylqm
eea7ff26f2 v5.10.0 2020-12-18 11:17:07 +08:00
sunnylqm
684dc8267d Back compatibility 2020-12-18 11:16:49 +08:00
sunnylqm
5786bf8132 v5.10.0-beta0 2020-12-17 00:15:48 +08:00
sunnylqm
1bd5fbbc94 Refactor ios rollback 2020-12-17 00:12:30 +08:00
sunnylqm
cd2eb9417a Update gitignore 2020-11-03 16:17:24 +08:00
5 changed files with 106 additions and 36 deletions

1
.gitignore vendored
View File

@@ -42,3 +42,4 @@ node_modules/
npm-debug.log npm-debug.log
Example/**/update.json Example/**/update.json
yarn-error.log

View File

@@ -277,12 +277,12 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
} }
} }
private void copyFromResource(HashMap<String, ArrayList<File> > map) throws IOException { private void copyFromResource(HashMap<String, ArrayList<File> > resToCopy) throws IOException {
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(context.getPackageResourcePath()))); ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(context.getPackageResourcePath())));
ZipEntry ze; ZipEntry ze;
while ((ze = zis.getNextEntry()) != null) { while ((ze = zis.getNextEntry()) != null) {
String fn = ze.getName(); String fn = ze.getName();
ArrayList<File> targets = map.get(fn); ArrayList<File> targets = resToCopy.get(fn);
if (targets != null) { if (targets != null) {
File lastTarget = null; File lastTarget = null;
for (File target: targets) { for (File target: targets) {
@@ -307,6 +307,8 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
ZipEntry ze; ZipEntry ze;
int count; int count;
String filename; String filename;
boolean foundDiff = false;
boolean foundBundlePatch = false;
removeDirectory(param.unzipDirectory); removeDirectory(param.unzipDirectory);
param.unzipDirectory.mkdirs(); param.unzipDirectory.mkdirs();
@@ -318,6 +320,7 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
String fn = ze.getName(); String fn = ze.getName();
if (fn.equals("__diff.json")) { if (fn.equals("__diff.json")) {
foundDiff = true;
// copy files from assets // copy files from assets
byte[] bytes = readBytes(zis); byte[] bytes = readBytes(zis);
String json = new String(bytes, "UTF-8"); String json = new String(bytes, "UTF-8");
@@ -344,6 +347,7 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
continue; continue;
} }
if (fn.equals("index.bundlejs.patch")) { if (fn.equals("index.bundlejs.patch")) {
foundBundlePatch = true;
// do bsdiff patch // do bsdiff patch
byte[] patched = bsdiffPatch(readOriginBundle(), readBytes(zis)); byte[] patched = bsdiffPatch(readOriginBundle(), readBytes(zis));
@@ -367,6 +371,12 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
} }
zis.close(); zis.close();
if (!foundDiff) {
throw new Error("diff.json not found");
}
if (!foundBundlePatch) {
throw new Error("bundle patch not found");
}
copyFromResource(copyList); copyFromResource(copyList);
@@ -383,6 +393,8 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
ZipEntry ze; ZipEntry ze;
int count; int count;
String filename; String filename;
boolean foundDiff = false;
boolean foundBundlePatch = false;
removeDirectory(param.unzipDirectory); removeDirectory(param.unzipDirectory);
param.unzipDirectory.mkdirs(); param.unzipDirectory.mkdirs();
@@ -392,6 +404,7 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
String fn = ze.getName(); String fn = ze.getName();
if (fn.equals("__diff.json")) { if (fn.equals("__diff.json")) {
foundDiff = true;
// copy files from assets // copy files from assets
byte[] bytes = readBytes(zis); byte[] bytes = readBytes(zis);
String json = new String(bytes, "UTF-8"); String json = new String(bytes, "UTF-8");
@@ -412,6 +425,7 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
continue; continue;
} }
if (fn.equals("index.bundlejs.patch")) { if (fn.equals("index.bundlejs.patch")) {
foundBundlePatch = true;
// do bsdiff patch // do bsdiff patch
byte[] patched = bsdiffPatch(readFile(new File(param.originDirectory, "index.bundlejs")), readBytes(zis)); byte[] patched = bsdiffPatch(readFile(new File(param.originDirectory, "index.bundlejs")), readBytes(zis));
@@ -436,6 +450,12 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
zis.close(); zis.close();
if (!foundDiff) {
throw new Error("diff.json not found");
}
if (!foundBundlePatch) {
throw new Error("bundle patch not found");
}
if (UpdateContext.DEBUG) { if (UpdateContext.DEBUG) {
Log.d("RNUpdate", "Unzip finished"); Log.d("RNUpdate", "Unzip finished");
} }
@@ -462,8 +482,9 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
@Override @Override
protected Void doInBackground(DownloadTaskParams... params) { protected Void doInBackground(DownloadTaskParams... params) {
int taskType = params[0].type;
try { try {
switch (params[0].type) { switch (taskType) {
case DownloadTaskParams.TASK_TYPE_PATCH_FULL: case DownloadTaskParams.TASK_TYPE_PATCH_FULL:
doFullPatch(params[0]); doFullPatch(params[0]);
break; break;
@@ -489,6 +510,25 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
if (UpdateContext.DEBUG) { if (UpdateContext.DEBUG) {
e.printStackTrace(); e.printStackTrace();
} }
File targetToClean = params[0].targetFile;
switch (taskType) {
case DownloadTaskParams.TASK_TYPE_PATCH_FULL:
case DownloadTaskParams.TASK_TYPE_PATCH_FROM_APK:
case DownloadTaskParams.TASK_TYPE_PATCH_FROM_PPK:
try {
removeDirectory(targetToClean);
} catch (IOException ioException) {
ioException.printStackTrace();
}
break;
case DownloadTaskParams.TASK_TYPE_PLAIN_DOWNLOAD:
if (targetToClean.exists()) {
targetToClean.delete();
}
break;
default:
break;
}
Log.e("pushy", "download task failed", e); Log.e("pushy", "download task failed", e);
params[0].listener.onDownloadFailed(e); params[0].listener.onDownloadFailed(e);
} }

View File

@@ -31,13 +31,14 @@ import static android.support.v4.content.FileProvider.getUriForFile;
/** /**
* Created by tdzl2003 on 3/31/16. * Created by tdzl2003 on 3/31/16.
*/ */
public class UpdateModule extends ReactContextBaseJavaModule{ public class UpdateModule extends ReactContextBaseJavaModule {
UpdateContext updateContext; UpdateContext updateContext;
public static ReactApplicationContext mContext; public static ReactApplicationContext mContext;
public UpdateModule(ReactApplicationContext reactContext, UpdateContext updateContext) { public UpdateModule(ReactApplicationContext reactContext, UpdateContext updateContext) {
super(reactContext); super(reactContext);
this.updateContext = updateContext; this.updateContext = updateContext;
mContext=reactContext; mContext = reactContext;
} }
public UpdateModule(ReactApplicationContext reactContext) { public UpdateModule(ReactApplicationContext reactContext) {
@@ -73,7 +74,7 @@ public class UpdateModule extends ReactContextBaseJavaModule{
} }
@ReactMethod @ReactMethod
public void downloadUpdate(ReadableMap options, final Promise promise){ public void downloadUpdate(ReadableMap options, final Promise promise) {
String url = options.getString("updateUrl"); String url = options.getString("updateUrl");
String hash = options.getString("hash"); String hash = options.getString("hash");
updateContext.downloadFullUpdate(url, hash, new UpdateContext.DownloadFileListener() { updateContext.downloadFullUpdate(url, hash, new UpdateContext.DownloadFileListener() {
@@ -90,7 +91,7 @@ public class UpdateModule extends ReactContextBaseJavaModule{
} }
@ReactMethod @ReactMethod
public void downloadAndInstallApk(ReadableMap options, final Promise promise){ public void downloadAndInstallApk(ReadableMap options, final Promise promise) {
String url = options.getString("url"); String url = options.getString("url");
String hash = options.getString("hash"); String hash = options.getString("hash");
String target = options.getString("target"); String target = options.getString("target");
@@ -136,9 +137,12 @@ public class UpdateModule extends ReactContextBaseJavaModule{
@ReactMethod @ReactMethod
public void downloadPatchFromPackage(ReadableMap options, final Promise promise){ public void downloadPatchFromPackage(ReadableMap options, final Promise promise) {
String url = options.getString("updateUrl"); String url = options.getString("updateUrl");
String hash = options.getString("hash"); String hash = options.getString("hash");
if (hash == null) {
hash = options.getString("hashName");
}
updateContext.downloadPatchFromApk(url, hash, new UpdateContext.DownloadFileListener() { updateContext.downloadPatchFromApk(url, hash, new UpdateContext.DownloadFileListener() {
@Override @Override
public void onDownloadCompleted(DownloadTaskParams params) { public void onDownloadCompleted(DownloadTaskParams params) {
@@ -153,10 +157,16 @@ public class UpdateModule extends ReactContextBaseJavaModule{
} }
@ReactMethod @ReactMethod
public void downloadPatchFromPpk(ReadableMap options, final Promise promise){ public void downloadPatchFromPpk(ReadableMap options, final Promise promise) {
String url = options.getString("updateUrl"); String url = options.getString("updateUrl");
String hash = options.getString("hash"); String hash = options.getString("hash");
if (hash == null) {
hash = options.getString("hashName");
}
String originHash = options.getString("originHash"); String originHash = options.getString("originHash");
if (originHash == null) {
originHash = options.getString(("originHashName"));
}
updateContext.downloadPatchFromPpk(url, hash, originHash, new UpdateContext.DownloadFileListener() { updateContext.downloadPatchFromPpk(url, hash, originHash, new UpdateContext.DownloadFileListener() {
@Override @Override
public void onDownloadCompleted(DownloadTaskParams params) { public void onDownloadCompleted(DownloadTaskParams params) {
@@ -172,7 +182,8 @@ public class UpdateModule extends ReactContextBaseJavaModule{
@ReactMethod @ReactMethod
public void reloadUpdate(ReadableMap options) { public void reloadUpdate(ReadableMap options) {
final String hash = options.getString("hash"); final String hash = options.getString("hash") == null ?
options.getString("hashName") : options.getString("hash");
UiThreadUtil.runOnUiThread(new Runnable() { UiThreadUtil.runOnUiThread(new Runnable() {
@Override @Override
@@ -200,7 +211,7 @@ public class UpdateModule extends ReactContextBaseJavaModule{
try { try {
instanceManager.recreateReactContextInBackground(); instanceManager.recreateReactContextInBackground();
} catch(Throwable err) { } catch (Throwable err) {
activity.recreate(); activity.recreate();
} }
@@ -213,7 +224,8 @@ public class UpdateModule extends ReactContextBaseJavaModule{
@ReactMethod @ReactMethod
public void setNeedUpdate(ReadableMap options) { public void setNeedUpdate(ReadableMap options) {
final String hash = options.getString("hash"); final String hash = options.getString("hash") == null ?
options.getString("hashName") : options.getString("hash");
UiThreadUtil.runOnUiThread(new Runnable() { UiThreadUtil.runOnUiThread(new Runnable() {
@Override @Override
@@ -260,7 +272,7 @@ public class UpdateModule extends ReactContextBaseJavaModule{
} }
/* 发送事件*/ /* 发送事件*/
public static void sendEvent(String eventName, WritableMap params) { public static void sendEvent(String eventName, WritableMap params) {
((ReactContext) mContext).getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, ((ReactContext) mContext).getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName,
params); params);
} }

View File

@@ -84,7 +84,6 @@ RCT_EXPORT_MODULE(RCTPushy);
} }
else { else {
NSString *curVersion = pushyInfo[paramCurrentVersion]; NSString *curVersion = pushyInfo[paramCurrentVersion];
NSString *lastVersion = pushyInfo[paramLastVersion];
BOOL isFirstTime = [pushyInfo[paramIsFirstTime] boolValue]; BOOL isFirstTime = [pushyInfo[paramIsFirstTime] boolValue];
BOOL isFirstLoadOK = [pushyInfo[paramIsFirstLoadOk] boolValue]; BOOL isFirstLoadOK = [pushyInfo[paramIsFirstLoadOk] boolValue];
@@ -92,23 +91,7 @@ RCT_EXPORT_MODULE(RCTPushy);
NSString *loadVersion = curVersion; NSString *loadVersion = curVersion;
BOOL needRollback = (!ignoreRollback && isFirstTime == NO && isFirstLoadOK == NO) || loadVersion.length<=0; BOOL needRollback = (!ignoreRollback && isFirstTime == NO && isFirstLoadOK == NO) || loadVersion.length<=0;
if (needRollback) { if (needRollback) {
loadVersion = lastVersion; loadVersion = [self rollback];
if (lastVersion.length) {
// roll back to last version
[defaults setObject:@{paramCurrentVersion:lastVersion,
paramIsFirstTime:@(NO),
paramIsFirstLoadOk:@(YES),
paramPackageVersion:curPackageVersion}
forKey:keyPushyInfo];
}
else {
// roll back to bundle
[defaults setObject:nil forKey:keyPushyInfo];
}
[defaults setObject:@(YES) forKey:keyRolledBackMarked];
[defaults synchronize];
// ...need clear files later
} }
else if (isFirstTime && !ignoreRollback){ else if (isFirstTime && !ignoreRollback){
// bundleURL may be called many times, ignore rollbacks before process restarted again. // bundleURL may be called many times, ignore rollbacks before process restarted again.
@@ -121,13 +104,15 @@ RCT_EXPORT_MODULE(RCTPushy);
[defaults synchronize]; [defaults synchronize];
} }
if (loadVersion.length) { NSString *downloadDir = [RCTPushy downloadDir];
NSString *downloadDir = [RCTPushy downloadDir]; while (loadVersion.length) {
NSString *bundlePath = [[downloadDir stringByAppendingPathComponent:loadVersion] stringByAppendingPathComponent:BUNDLE_FILE_NAME]; NSString *bundlePath = [[downloadDir stringByAppendingPathComponent:loadVersion] stringByAppendingPathComponent:BUNDLE_FILE_NAME];
if ([[NSFileManager defaultManager] fileExistsAtPath:bundlePath isDirectory:NULL]) { if ([[NSFileManager defaultManager] fileExistsAtPath:bundlePath isDirectory:NULL]) {
NSURL *bundleURL = [NSURL fileURLWithPath:bundlePath]; NSURL *bundleURL = [NSURL fileURLWithPath:bundlePath];
return bundleURL; return bundleURL;
} else {
RCTLogError(@"RCTPushy -- bundle version %@ not found", loadVersion);
loadVersion = [self rollback];
} }
} }
} }
@@ -136,6 +121,29 @@ RCT_EXPORT_MODULE(RCTPushy);
return [RCTPushy binaryBundleURL]; return [RCTPushy binaryBundleURL];
} }
+ (NSString *) rollback {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *pushyInfo = [defaults dictionaryForKey:keyPushyInfo];
NSString *lastVersion = pushyInfo[paramLastVersion];
NSString *curPackageVersion = [RCTPushy packageVersion];
if (lastVersion.length) {
// roll back to last version
[defaults setObject:@{paramCurrentVersion:lastVersion,
paramIsFirstTime:@(NO),
paramIsFirstLoadOk:@(YES),
paramPackageVersion:curPackageVersion}
forKey:keyPushyInfo];
}
else {
// roll back to bundle
[defaults setObject:nil forKey:keyPushyInfo];
}
[defaults setObject:@(YES) forKey:keyRolledBackMarked];
[defaults synchronize];
return lastVersion;
}
+ (BOOL)requiresMainQueueSetup { + (BOOL)requiresMainQueueSetup {
// only set to YES if your module initialization relies on calling UIKit! // only set to YES if your module initialization relies on calling UIKit!
return NO; return NO;
@@ -248,6 +256,9 @@ RCT_EXPORT_METHOD(downloadPatchFromPpk:(NSDictionary *)options
RCT_EXPORT_METHOD(setNeedUpdate:(NSDictionary *)options) RCT_EXPORT_METHOD(setNeedUpdate:(NSDictionary *)options)
{ {
NSString *hash = options[@"hash"]; NSString *hash = options[@"hash"];
if (hash.length <= 0) {
hash = options[@"hashName"];
}
if (hash.length) { if (hash.length) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *lastVersion = nil; NSString *lastVersion = nil;
@@ -271,6 +282,9 @@ RCT_EXPORT_METHOD(setNeedUpdate:(NSDictionary *)options)
RCT_EXPORT_METHOD(reloadUpdate:(NSDictionary *)options) RCT_EXPORT_METHOD(reloadUpdate:(NSDictionary *)options)
{ {
NSString *hash = options[@"hash"]; NSString *hash = options[@"hash"];
if (hash.length <= 0) {
hash = options[@"hashName"];
}
if (hash.length) { if (hash.length) {
[self setNeedUpdate:options]; [self setNeedUpdate:options];
@@ -327,6 +341,9 @@ RCT_EXPORT_METHOD(markSuccess)
{ {
NSString *updateUrl = [RCTConvert NSString:options[@"updateUrl"]]; NSString *updateUrl = [RCTConvert NSString:options[@"updateUrl"]];
NSString *hash = [RCTConvert NSString:options[@"hash"]]; NSString *hash = [RCTConvert NSString:options[@"hash"]];
if (hash.length <= 0) {
hash = [RCTConvert NSString:options[@"hashName"]];;
}
if (updateUrl.length <= 0 || hash.length <= 0) { if (updateUrl.length <= 0 || hash.length <= 0) {
callback([self errorWithMessage:ERROR_OPTIONS]); callback([self errorWithMessage:ERROR_OPTIONS]);
return; return;

View File

@@ -1,6 +1,6 @@
{ {
"name": "react-native-update", "name": "react-native-update",
"version": "5.9.3", "version": "5.11.0-beta0",
"description": "react-native hot update", "description": "react-native hot update",
"main": "lib/index.js", "main": "lib/index.js",
"scripts": { "scripts": {