mirror of
https://github.com/zhigang1992/react-native-code-push.git
synced 2026-06-11 08:04:23 +08:00
Adding isPending
This commit is contained in:
@@ -38,7 +38,6 @@ import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class CodePush {
|
||||
|
||||
private boolean didUpdate = false;
|
||||
private boolean usingTestFolder = false;
|
||||
|
||||
@@ -89,13 +88,13 @@ public class CodePush {
|
||||
initializeUpdateAfterRestart();
|
||||
}
|
||||
|
||||
public ReactPackage getReactPackage() {
|
||||
if (codePushReactPackage == null) {
|
||||
codePushReactPackage = new CodePushReactPackage();
|
||||
private void clearReactDevBundleCache() {
|
||||
File cachedDevBundle = new File(this.applicationContext.getFilesDir(), REACT_DEV_BUNDLE_CACHE_FILE_NAME);
|
||||
if (cachedDevBundle.exists()) {
|
||||
cachedDevBundle.delete();
|
||||
}
|
||||
return codePushReactPackage;
|
||||
}
|
||||
|
||||
|
||||
public long getBinaryResourcesModifiedTime() {
|
||||
ApplicationInfo ai = null;
|
||||
ZipFile applicationFile = null;
|
||||
@@ -148,6 +147,57 @@ public class CodePush {
|
||||
}
|
||||
}
|
||||
|
||||
private JSONObject getPendingUpdate() {
|
||||
SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0);
|
||||
String pendingUpdateString = settings.getString(PENDING_UPDATE_KEY, null);
|
||||
if (pendingUpdateString == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
JSONObject pendingUpdate = new JSONObject(pendingUpdateString);
|
||||
return pendingUpdate;
|
||||
} catch (JSONException e) {
|
||||
// Should not happen.
|
||||
CodePushUtils.log("Unable to parse pending update metadata " + pendingUpdateString +
|
||||
" stored in SharedPreferences");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public ReactPackage getReactPackage() {
|
||||
if (codePushReactPackage == null) {
|
||||
codePushReactPackage = new CodePushReactPackage();
|
||||
}
|
||||
return codePushReactPackage;
|
||||
}
|
||||
|
||||
private void initializeUpdateAfterRestart() {
|
||||
JSONObject pendingUpdate = getPendingUpdate();
|
||||
if (pendingUpdate != null) {
|
||||
didUpdate = true;
|
||||
try {
|
||||
boolean updateIsLoading = pendingUpdate.getBoolean(PENDING_UPDATE_IS_LOADING_KEY);
|
||||
if (updateIsLoading) {
|
||||
// Pending update was initialized, but notifyApplicationReady was not called.
|
||||
// Therefore, deduce that it is a broken update and rollback.
|
||||
CodePushUtils.log("Update did not finish loading the last time, rolling back to a previous version.");
|
||||
rollbackPackage();
|
||||
} else {
|
||||
// Clear the React dev bundle cache so that new updates can be loaded.
|
||||
clearReactDevBundleCache();
|
||||
// Mark that we tried to initialize the new update, so that if it crashes,
|
||||
// we will know that we need to rollback when the app next starts.
|
||||
savePendingUpdate(pendingUpdate.getString(PENDING_UPDATE_HASH_KEY),
|
||||
/* isLoading */true);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
// Should not happen.
|
||||
throw new CodePushUnknownException("Unable to read pending update metadata stored in SharedPreferences", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isFailedHash(String packageHash) {
|
||||
SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0);
|
||||
String failedUpdatesString = settings.getString(FAILED_UPDATES_KEY, null);
|
||||
@@ -165,6 +215,26 @@ public class CodePush {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPendingUpdate(String packageHash) {
|
||||
JSONObject pendingUpdate = getPendingUpdate();
|
||||
|
||||
try {
|
||||
boolean updateIsPending = pendingUpdate != null &&
|
||||
pendingUpdate.getBoolean(PENDING_UPDATE_IS_LOADING_KEY) == false &&
|
||||
pendingUpdate.getString(PENDING_UPDATE_HASH_KEY).equals(packageHash);
|
||||
|
||||
return updateIsPending;
|
||||
}
|
||||
catch (JSONException e) {
|
||||
throw new CodePushUnknownException("Unable to read pending update metadata in isPendingUpdate.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void removePendingUpdate() {
|
||||
SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0);
|
||||
settings.edit().remove(PENDING_UPDATE_KEY).commit();
|
||||
}
|
||||
|
||||
private void rollbackPackage() {
|
||||
try {
|
||||
String packageHash = codePushPackage.getCurrentPackageHash();
|
||||
@@ -207,11 +277,6 @@ public class CodePush {
|
||||
}
|
||||
}
|
||||
|
||||
private void removePendingUpdate() {
|
||||
SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0);
|
||||
settings.edit().remove(PENDING_UPDATE_KEY).commit();
|
||||
}
|
||||
|
||||
private void savePendingUpdate(String packageHash, boolean isLoading) {
|
||||
SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0);
|
||||
JSONObject pendingUpdate = new JSONObject();
|
||||
@@ -225,57 +290,6 @@ public class CodePush {
|
||||
}
|
||||
}
|
||||
|
||||
private JSONObject getPendingUpdate() {
|
||||
SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0);
|
||||
String pendingUpdateString = settings.getString(PENDING_UPDATE_KEY, null);
|
||||
if (pendingUpdateString == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
JSONObject pendingUpdate = new JSONObject(pendingUpdateString);
|
||||
return pendingUpdate;
|
||||
} catch (JSONException e) {
|
||||
// Should not happen.
|
||||
CodePushUtils.log("Unable to parse pending update metadata " + pendingUpdateString +
|
||||
" stored in SharedPreferences");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeUpdateAfterRestart() {
|
||||
JSONObject pendingUpdate = getPendingUpdate();
|
||||
if (pendingUpdate != null) {
|
||||
didUpdate = true;
|
||||
try {
|
||||
boolean updateIsLoading = pendingUpdate.getBoolean(PENDING_UPDATE_IS_LOADING_KEY);
|
||||
if (updateIsLoading) {
|
||||
// Pending update was initialized, but notifyApplicationReady was not called.
|
||||
// Therefore, deduce that it is a broken update and rollback.
|
||||
CodePushUtils.log("Update did not finish loading the last time, rolling back to a previous version.");
|
||||
rollbackPackage();
|
||||
} else {
|
||||
// Clear the React dev bundle cache so that new updates can be loaded.
|
||||
clearReactDevBundleCache();
|
||||
// Mark that we tried to initialize the new update, so that if it crashes,
|
||||
// we will know that we need to rollback when the app next starts.
|
||||
savePendingUpdate(pendingUpdate.getString(PENDING_UPDATE_HASH_KEY),
|
||||
/* isLoading */true);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
// Should not happen.
|
||||
throw new CodePushUnknownException("Unable to read pending update metadata stored in SharedPreferences", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void clearReactDevBundleCache() {
|
||||
File cachedDevBundle = new File(this.applicationContext.getFilesDir(), REACT_DEV_BUNDLE_CACHE_FILE_NAME);
|
||||
if (cachedDevBundle.exists()) {
|
||||
cachedDevBundle.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private class CodePushNativeModule extends ReactContextBaseJavaModule {
|
||||
|
||||
private LifecycleEventListener lifecycleEventListener = null;
|
||||
@@ -286,11 +300,81 @@ public class CodePush {
|
||||
mainActivity.startActivity(intent);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void downloadUpdate(final ReadableMap updatePackage, final Promise promise) {
|
||||
AsyncTask asyncTask = new AsyncTask() {
|
||||
@Override
|
||||
protected Void doInBackground(Object... params) {
|
||||
try {
|
||||
WritableMap mutableUpdatePackage = CodePushUtils.convertReadableMapToWritableMap(updatePackage);
|
||||
mutableUpdatePackage.putString(BINARY_MODIFIED_TIME_KEY, "" + getBinaryResourcesModifiedTime());
|
||||
codePushPackage.downloadPackage(applicationContext, mutableUpdatePackage, new DownloadProgressCallback() {
|
||||
@Override
|
||||
public void call(DownloadProgress downloadProgress) {
|
||||
getReactApplicationContext()
|
||||
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
||||
.emit(DOWNLOAD_PROGRESS_EVENT_NAME, downloadProgress.createWritableMap());
|
||||
}
|
||||
});
|
||||
|
||||
WritableMap newPackage = codePushPackage.getPackage(CodePushUtils.tryGetString(updatePackage, codePushPackage.PACKAGE_HASH_KEY));
|
||||
promise.resolve(newPackage);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
promise.reject(e.getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
asyncTask.execute();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getConfiguration(Promise promise) {
|
||||
WritableNativeMap configMap = new WritableNativeMap();
|
||||
configMap.putString("appVersion", appVersion);
|
||||
configMap.putInt("buildVersion", buildVersion);
|
||||
configMap.putString("deploymentKey", deploymentKey);
|
||||
configMap.putString("serverUrl", serverUrl);
|
||||
promise.resolve(configMap);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getCurrentPackage(final Promise promise) {
|
||||
AsyncTask asyncTask = new AsyncTask() {
|
||||
@Override
|
||||
protected Void doInBackground(Object... params) {
|
||||
try {
|
||||
WritableMap currentPackage = codePushPackage.getCurrentPackage();
|
||||
|
||||
Boolean isPendingUpdate = false;
|
||||
|
||||
if (currentPackage.hasKey(codePushPackage.PACKAGE_HASH_KEY)) {
|
||||
String currentHash = currentPackage.getString(codePushPackage.PACKAGE_HASH_KEY);
|
||||
isPendingUpdate = CodePush.this.isPendingUpdate(currentHash);
|
||||
}
|
||||
|
||||
currentPackage.putBoolean("isPending", isPendingUpdate);
|
||||
promise.resolve(currentPackage);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
promise.reject(e.getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
asyncTask.execute();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void installUpdate(final ReadableMap updatePackage, final int installMode, final Promise promise) {
|
||||
AsyncTask asyncTask = new AsyncTask() {
|
||||
@Override
|
||||
protected Void doInBackground(Object[] params) {
|
||||
protected Void doInBackground(Object... params) {
|
||||
try {
|
||||
codePushPackage.installPackage(updatePackage);
|
||||
|
||||
@@ -336,67 +420,7 @@ public class CodePush {
|
||||
|
||||
asyncTask.execute();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void downloadUpdate(final ReadableMap updatePackage, final Promise promise) {
|
||||
AsyncTask asyncTask = new AsyncTask() {
|
||||
@Override
|
||||
protected Void doInBackground(Object[] params) {
|
||||
try {
|
||||
WritableMap mutableUpdatePackage = CodePushUtils.convertReadableMapToWritableMap(updatePackage);
|
||||
mutableUpdatePackage.putString(BINARY_MODIFIED_TIME_KEY, "" + getBinaryResourcesModifiedTime());
|
||||
codePushPackage.downloadPackage(applicationContext, mutableUpdatePackage, new DownloadProgressCallback() {
|
||||
@Override
|
||||
public void call(DownloadProgress downloadProgress) {
|
||||
getReactApplicationContext()
|
||||
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
||||
.emit(DOWNLOAD_PROGRESS_EVENT_NAME, downloadProgress.createWritableMap());
|
||||
}
|
||||
});
|
||||
|
||||
WritableMap newPackage = codePushPackage.getPackage(CodePushUtils.tryGetString(updatePackage, codePushPackage.PACKAGE_HASH_KEY));
|
||||
promise.resolve(newPackage);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
promise.reject(e.getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
asyncTask.execute();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getConfiguration(Promise promise) {
|
||||
WritableNativeMap configMap = new WritableNativeMap();
|
||||
configMap.putString("appVersion", appVersion);
|
||||
configMap.putInt("buildVersion", buildVersion);
|
||||
configMap.putString("deploymentKey", deploymentKey);
|
||||
configMap.putString("serverUrl", serverUrl);
|
||||
promise.resolve(configMap);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getCurrentPackage(final Promise promise) {
|
||||
AsyncTask asyncTask = new AsyncTask() {
|
||||
@Override
|
||||
protected Void doInBackground(Object[] params) {
|
||||
try {
|
||||
promise.resolve(codePushPackage.getCurrentPackage());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
promise.reject(e.getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
asyncTask.execute();
|
||||
}
|
||||
|
||||
|
||||
@ReactMethod
|
||||
public void isFailedUpdate(String packageHash, Promise promise) {
|
||||
promise.resolve(isFailedHash(packageHash));
|
||||
@@ -421,17 +445,17 @@ public class CodePush {
|
||||
removePendingUpdate();
|
||||
promise.resolve("");
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void restartApp() {
|
||||
loadBundle();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setUsingTestFolder(boolean shouldUseTestFolder) {
|
||||
usingTestFolder = shouldUseTestFolder;
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void restartApp() {
|
||||
loadBundle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getConstants() {
|
||||
final Map<String, Object> constants = new HashMap<>();
|
||||
@@ -474,5 +498,4 @@ public class CodePush {
|
||||
return new ArrayList();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user