mirror of
https://gitcode.com/gh_mirrors/re/react-native-pushy.git
synced 2025-11-24 00:13:36 +08:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f941b93cb3 | ||
|
|
bea0e077a0 |
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
|
"configVersion": 0,
|
||||||
"workspaces": {
|
"workspaces": {
|
||||||
"": {
|
"": {
|
||||||
"name": "testHotUpdate",
|
"name": "testHotUpdate",
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import { LocalSvg } from 'react-native-svg/css';
|
|||||||
import TestConsole from './TestConsole';
|
import TestConsole from './TestConsole';
|
||||||
|
|
||||||
import _updateConfig from '../update.json';
|
import _updateConfig from '../update.json';
|
||||||
import { UpdateProvider, Pushy, Cresc, useUpdate } from 'react-native-update';
|
import { UpdateProvider, Pushy, useUpdate } from 'react-native-update';
|
||||||
const { appKey } = _updateConfig[Platform.OS];
|
const { appKey } = _updateConfig[Platform.OS];
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
@@ -53,7 +53,7 @@ function App() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.welcome}>欢迎22使用Pushy热更新服务</Text>
|
<Text style={styles.welcome}>欢迎使用Pushy热更新服务</Text>
|
||||||
<View style={{ flexDirection: 'row' }}>
|
<View style={{ flexDirection: 'row' }}>
|
||||||
<Text>
|
<Text>
|
||||||
{useDefaultAlert ? '当前使用' : '当前不使用'}默认的alert更新提示
|
{useDefaultAlert ? '当前使用' : '当前不使用'}默认的alert更新提示
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package cn.reactnative.modules.update;
|
package cn.reactnative.modules.update;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Build;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import com.facebook.react.bridge.Arguments;
|
import com.facebook.react.bridge.Arguments;
|
||||||
import com.facebook.react.bridge.WritableMap;
|
import com.facebook.react.bridge.WritableMap;
|
||||||
@@ -25,7 +28,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.CRC32;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import okio.BufferedSink;
|
import okio.BufferedSink;
|
||||||
@@ -98,9 +100,6 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
while ((bytesRead = source.read(sink.buffer(), DOWNLOAD_CHUNK_SIZE)) != -1) {
|
while ((bytesRead = source.read(sink.buffer(), DOWNLOAD_CHUNK_SIZE)) != -1) {
|
||||||
received += bytesRead;
|
received += bytesRead;
|
||||||
sink.emit();
|
sink.emit();
|
||||||
if (UpdateContext.DEBUG) {
|
|
||||||
Log.d("react-native-update", "Progress " + received + "/" + contentLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
int percentage = (int)(received * 100.0 / contentLength + 0.5);
|
int percentage = (int)(received * 100.0 / contentLength + 0.5);
|
||||||
if (percentage > currentPercentage) {
|
if (percentage > currentPercentage) {
|
||||||
@@ -199,10 +198,6 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
return fout.toByteArray();
|
return fout.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getCRC32AsDecimal(long crc32Value) {
|
|
||||||
return String.valueOf(crc32Value & 0xFFFFFFFFL);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void copyFilesWithBlacklist(String current, File from, File to, JSONObject blackList) throws IOException {
|
private void copyFilesWithBlacklist(String current, File from, File to, JSONObject blackList) throws IOException {
|
||||||
File[] files = from.listFiles();
|
File[] files = from.listFiles();
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
@@ -252,57 +247,209 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyFromResource(HashMap<String, ArrayList<File> > resToCopy) throws IOException {
|
private String findDrawableFallback(String originalToPath, HashMap<String, String> copiesMap, HashMap<String, ZipEntry> availableEntries) {
|
||||||
SafeZipFile zipFile = new SafeZipFile(new File(context.getPackageResourcePath()));
|
// 检查是否是 drawable 路径
|
||||||
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
if (!originalToPath.contains("drawable")) {
|
||||||
while (entries.hasMoreElements()) {
|
return null;
|
||||||
ZipEntry ze = entries.nextElement();
|
}
|
||||||
|
|
||||||
String fn = ze.getName();
|
// 提取文件名(路径的最后部分)
|
||||||
ArrayList<File> targets = resToCopy.get(fn);
|
int lastSlash = originalToPath.lastIndexOf('/');
|
||||||
if (targets != null) {
|
if (lastSlash == -1) {
|
||||||
File lastTarget = null;
|
return null;
|
||||||
for (File target: targets) {
|
}
|
||||||
|
String fileName = originalToPath.substring(lastSlash + 1);
|
||||||
|
|
||||||
|
// 定义密度优先级(从高到低)
|
||||||
|
String[] densities = {"xxxhdpi", "xxhdpi", "xhdpi", "hdpi", "mdpi", "ldpi"};
|
||||||
|
|
||||||
|
// 尝试找到相同文件名但不同密度的 key
|
||||||
|
for (String density : densities) {
|
||||||
|
// 构建可能的 key 路径(替换密度部分)
|
||||||
|
String fallbackToPath = originalToPath.replaceFirst("drawable-[^/]+", "drawable-" + density);
|
||||||
|
|
||||||
|
// 检查这个 key 是否在 copies 映射中
|
||||||
|
if (copiesMap.containsKey(fallbackToPath)) {
|
||||||
|
String fallbackFromPath = copiesMap.get(fallbackToPath);
|
||||||
|
// 检查对应的 value 路径是否在 APK 中存在
|
||||||
|
if (availableEntries.containsKey(fallbackFromPath)) {
|
||||||
if (UpdateContext.DEBUG) {
|
if (UpdateContext.DEBUG) {
|
||||||
Log.d("react-native-update", "Copying from resource " + fn + " to " + target);
|
Log.d("react-native-update", "Found fallback for " + originalToPath + ": " + fallbackToPath + " -> " + fallbackFromPath);
|
||||||
}
|
|
||||||
if (lastTarget != null) {
|
|
||||||
copyFile(lastTarget, target);
|
|
||||||
} else {
|
|
||||||
zipFile.unzipToFile(ze, target);
|
|
||||||
lastTarget = target;
|
|
||||||
}
|
}
|
||||||
|
return fallbackFromPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zipFile.close();
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyFromResourceV2(HashMap<String, ArrayList<File>> resToCopy2) throws IOException {
|
private void copyFromResource(HashMap<String, ArrayList<File> > resToCopy, HashMap<String, String> copiesMap) throws IOException {
|
||||||
SafeZipFile zipFile = new SafeZipFile(new File(context.getPackageResourcePath()));
|
if (UpdateContext.DEBUG) {
|
||||||
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
Log.d("react-native-update", "copyFromResource called, resToCopy size: " + resToCopy.size());
|
||||||
while (entries.hasMoreElements()) {
|
}
|
||||||
ZipEntry ze = entries.nextElement();
|
|
||||||
String fn = ze.getName();
|
// 收集所有 APK 路径(包括基础 APK 和所有 split APK)
|
||||||
long zipCrc32 = ze.getCrc();
|
ArrayList<String> apkPaths = new ArrayList<>();
|
||||||
String crc32Decimal = getCRC32AsDecimal(zipCrc32);
|
apkPaths.add(context.getPackageResourcePath());
|
||||||
ArrayList<File> targets = resToCopy2.get(crc32Decimal);
|
|
||||||
if (targets != null) {
|
// 获取所有 split APK 路径(用于资源分割的情况)
|
||||||
File lastTarget = null;
|
try {
|
||||||
for (File target: targets) {
|
ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(
|
||||||
|
context.getPackageName(), 0);
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && appInfo.splitSourceDirs != null) {
|
||||||
|
for (String splitPath : appInfo.splitSourceDirs) {
|
||||||
|
apkPaths.add(splitPath);
|
||||||
if (UpdateContext.DEBUG) {
|
if (UpdateContext.DEBUG) {
|
||||||
Log.d("react-native-update", "Copying from resource " + fn + " to " + target);
|
Log.d("react-native-update", "Found split APK: " + splitPath);
|
||||||
}
|
|
||||||
if (lastTarget != null) {
|
|
||||||
copyFile(lastTarget, target);
|
|
||||||
} else {
|
|
||||||
zipFile.unzipToFile(ze, target);
|
|
||||||
lastTarget = target;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
if (UpdateContext.DEBUG) {
|
||||||
|
Log.w("react-native-update", "Failed to get application info: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第一遍:从所有 APK 中收集所有可用的 zip 条目
|
||||||
|
HashMap<String, ZipEntry> availableEntries = new HashMap<>();
|
||||||
|
HashMap<String, SafeZipFile> zipFileMap = new HashMap<>(); // 保存每个路径对应的 ZipFile
|
||||||
|
HashMap<String, SafeZipFile> entryToZipFileMap = new HashMap<>(); // 保存每个条目对应的 ZipFile
|
||||||
|
|
||||||
|
for (String apkPath : apkPaths) {
|
||||||
|
SafeZipFile zipFile = new SafeZipFile(new File(apkPath));
|
||||||
|
zipFileMap.put(apkPath, zipFile);
|
||||||
|
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||||
|
while (entries.hasMoreElements()) {
|
||||||
|
ZipEntry ze = entries.nextElement();
|
||||||
|
String entryName = ze.getName();
|
||||||
|
// 如果条目已存在,保留第一个(基础 APK 优先)
|
||||||
|
if (!availableEntries.containsKey(entryName)) {
|
||||||
|
availableEntries.put(entryName, ze);
|
||||||
|
entryToZipFileMap.put(entryName, zipFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用基础 APK 的 ZipFile 作为主要操作对象
|
||||||
|
SafeZipFile zipFile = zipFileMap.get(context.getPackageResourcePath());
|
||||||
|
|
||||||
|
// 处理所有需要复制的文件
|
||||||
|
HashMap<String, ArrayList<File>> remainingFiles = new HashMap<>(resToCopy);
|
||||||
|
|
||||||
|
for (String fromPath : new ArrayList<>(remainingFiles.keySet())) {
|
||||||
|
if (UpdateContext.DEBUG) {
|
||||||
|
Log.d("react-native-update", "Processing fromPath: " + fromPath);
|
||||||
|
}
|
||||||
|
ArrayList<File> targets = remainingFiles.get(fromPath);
|
||||||
|
if (targets == null || targets.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZipEntry ze = availableEntries.get(fromPath);
|
||||||
|
String actualSourcePath = fromPath;
|
||||||
|
|
||||||
|
// 如果文件不存在,尝试 fallback
|
||||||
|
if (ze == null) {
|
||||||
|
if (UpdateContext.DEBUG) {
|
||||||
|
Log.d("react-native-update", "File not found in APK: " + fromPath + ", trying fallback");
|
||||||
|
}
|
||||||
|
// 找到对应的 to 路径(从 copiesMap 的反向查找)
|
||||||
|
String toPath = null;
|
||||||
|
for (String to : copiesMap.keySet()) {
|
||||||
|
if (copiesMap.get(to).equals(fromPath)) {
|
||||||
|
toPath = to;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toPath != null) {
|
||||||
|
if (UpdateContext.DEBUG) {
|
||||||
|
Log.d("react-native-update", "Found toPath: " + toPath + " for fromPath: " + fromPath);
|
||||||
|
}
|
||||||
|
String fallbackFromPath = findDrawableFallback(toPath, copiesMap, availableEntries);
|
||||||
|
if (fallbackFromPath != null) {
|
||||||
|
ze = availableEntries.get(fallbackFromPath);
|
||||||
|
actualSourcePath = fallbackFromPath;
|
||||||
|
// 确保 fallback 路径也在 entryToZipFileMap 中
|
||||||
|
if (!entryToZipFileMap.containsKey(fallbackFromPath)) {
|
||||||
|
// 查找包含该 fallback 路径的 ZipFile
|
||||||
|
for (String apkPath : apkPaths) {
|
||||||
|
SafeZipFile testZipFile = zipFileMap.get(apkPath);
|
||||||
|
if (testZipFile != null) {
|
||||||
|
try {
|
||||||
|
ZipEntry testEntry = testZipFile.getEntry(fallbackFromPath);
|
||||||
|
if (testEntry != null) {
|
||||||
|
entryToZipFileMap.put(fallbackFromPath, testZipFile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 继续查找
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (UpdateContext.DEBUG) {
|
||||||
|
Log.w("react-native-update", "Using fallback: " + fallbackFromPath + " for " + fromPath);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (UpdateContext.DEBUG) {
|
||||||
|
Log.w("react-native-update", "No fallback found for: " + fromPath + " (toPath: " + toPath + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (UpdateContext.DEBUG) {
|
||||||
|
Log.w("react-native-update", "No toPath found for fromPath: " + fromPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ze != null) {
|
||||||
|
File lastTarget = null;
|
||||||
|
for (File target: targets) {
|
||||||
|
if (UpdateContext.DEBUG) {
|
||||||
|
Log.d("react-native-update", "Copying from resource " + actualSourcePath + " to " + target);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// 确保目标文件的父目录存在
|
||||||
|
File parentDir = target.getParentFile();
|
||||||
|
if (parentDir != null && !parentDir.exists()) {
|
||||||
|
parentDir.mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastTarget != null) {
|
||||||
|
copyFile(lastTarget, target);
|
||||||
|
} else {
|
||||||
|
// 从保存的映射中获取包含该条目的 ZipFile
|
||||||
|
SafeZipFile sourceZipFile = entryToZipFileMap.get(actualSourcePath);
|
||||||
|
if (sourceZipFile == null) {
|
||||||
|
sourceZipFile = zipFile; // 回退到基础 APK
|
||||||
|
}
|
||||||
|
sourceZipFile.unzipToFile(ze, target);
|
||||||
|
lastTarget = target;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (UpdateContext.DEBUG) {
|
||||||
|
Log.w("react-native-update", "Failed to copy resource " + actualSourcePath + " to " + target + ": " + e.getMessage());
|
||||||
|
}
|
||||||
|
// 继续处理下一个目标
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remainingFiles.remove(fromPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理剩余的文件(如果还有的话)
|
||||||
|
if (!remainingFiles.isEmpty() && UpdateContext.DEBUG) {
|
||||||
|
for (String fromPath : remainingFiles.keySet()) {
|
||||||
|
Log.w("react-native-update", "Resource not found and no fallback available: " + fromPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭所有 ZipFile
|
||||||
|
for (SafeZipFile zf : zipFileMap.values()) {
|
||||||
|
zf.close();
|
||||||
}
|
}
|
||||||
zipFile.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doPatchFromApk(DownloadTaskParams param) throws IOException, JSONException {
|
private void doPatchFromApk(DownloadTaskParams param) throws IOException, JSONException {
|
||||||
@@ -311,8 +458,7 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
removeDirectory(param.unzipDirectory);
|
removeDirectory(param.unzipDirectory);
|
||||||
param.unzipDirectory.mkdirs();
|
param.unzipDirectory.mkdirs();
|
||||||
HashMap<String, ArrayList<File>> copyList = new HashMap<String, ArrayList<File>>();
|
HashMap<String, ArrayList<File>> copyList = new HashMap<String, ArrayList<File>>();
|
||||||
HashMap<String, ArrayList<File>> copiesv2List = new HashMap<String, ArrayList<File>>();
|
HashMap<String, String> copiesMap = new HashMap<String, String>(); // to -> from 映射
|
||||||
Boolean isV2 = false;
|
|
||||||
|
|
||||||
boolean foundDiff = false;
|
boolean foundDiff = false;
|
||||||
boolean foundBundlePatch = false;
|
boolean foundBundlePatch = false;
|
||||||
@@ -331,58 +477,32 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
JSONObject obj = (JSONObject)new JSONTokener(json).nextValue();
|
JSONObject obj = (JSONObject)new JSONTokener(json).nextValue();
|
||||||
|
|
||||||
JSONObject copies = obj.getJSONObject("copies");
|
JSONObject copies = obj.getJSONObject("copies");
|
||||||
JSONObject copiesv2 = obj.getJSONObject("copiesv2");
|
|
||||||
Iterator<?> keys = copies.keys();
|
Iterator<?> keys = copies.keys();
|
||||||
Iterator<?> keysV2 = copiesv2.keys();
|
while( keys.hasNext() ) {
|
||||||
if(keysV2.hasNext()){
|
String to = (String)keys.next();
|
||||||
isV2 = true;
|
String from = copies.getString(to);
|
||||||
while( keysV2.hasNext() ) {
|
if (from.isEmpty()) {
|
||||||
String from = (String)keysV2.next();
|
from = to;
|
||||||
String to = copiesv2.getString(from);
|
|
||||||
if (from.isEmpty()) {
|
|
||||||
from = to;
|
|
||||||
}
|
|
||||||
ArrayList<File> target = null;
|
|
||||||
if (!copiesv2List.containsKey(from)) {
|
|
||||||
target = new ArrayList<File>();
|
|
||||||
copiesv2List.put(from, target);
|
|
||||||
} else {
|
|
||||||
target = copiesv2List.get((from));
|
|
||||||
}
|
|
||||||
File toFile = new File(param.unzipDirectory, to);
|
|
||||||
|
|
||||||
// Fixing a Zip Path Traversal Vulnerability
|
|
||||||
// https://support.google.com/faqs/answer/9294009
|
|
||||||
String canonicalPath = toFile.getCanonicalPath();
|
|
||||||
if (!canonicalPath.startsWith(param.unzipDirectory.getCanonicalPath() + File.separator)) {
|
|
||||||
throw new SecurityException("Illegal name: " + to);
|
|
||||||
}
|
|
||||||
target.add(toFile);
|
|
||||||
}
|
}
|
||||||
}else{
|
// 保存 copies 映射关系(to -> from)
|
||||||
while( keys.hasNext() ) {
|
copiesMap.put(to, from);
|
||||||
String to = (String)keys.next();
|
|
||||||
String from = copies.getString(to);
|
|
||||||
if (from.isEmpty()) {
|
|
||||||
from = to;
|
|
||||||
}
|
|
||||||
ArrayList<File> target = null;
|
|
||||||
if (!copyList.containsKey(from)) {
|
|
||||||
target = new ArrayList<File>();
|
|
||||||
copyList.put(from, target);
|
|
||||||
} else {
|
|
||||||
target = copyList.get((from));
|
|
||||||
}
|
|
||||||
File toFile = new File(param.unzipDirectory, to);
|
|
||||||
|
|
||||||
// Fixing a Zip Path Traversal Vulnerability
|
ArrayList<File> target = null;
|
||||||
// https://support.google.com/faqs/answer/9294009
|
if (!copyList.containsKey(from)) {
|
||||||
String canonicalPath = toFile.getCanonicalPath();
|
target = new ArrayList<File>();
|
||||||
if (!canonicalPath.startsWith(param.unzipDirectory.getCanonicalPath() + File.separator)) {
|
copyList.put(from, target);
|
||||||
throw new SecurityException("Illegal name: " + to);
|
} else {
|
||||||
}
|
target = copyList.get((from));
|
||||||
target.add(toFile);
|
|
||||||
}
|
}
|
||||||
|
File toFile = new File(param.unzipDirectory, to);
|
||||||
|
|
||||||
|
// Fixing a Zip Path Traversal Vulnerability
|
||||||
|
// https://support.google.com/faqs/answer/9294009
|
||||||
|
String canonicalPath = toFile.getCanonicalPath();
|
||||||
|
if (!canonicalPath.startsWith(param.unzipDirectory.getCanonicalPath() + File.separator)) {
|
||||||
|
throw new SecurityException("Illegal name: " + to);
|
||||||
|
}
|
||||||
|
target.add(toFile);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -411,12 +531,15 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
|||||||
throw new Error("bundle patch not found");
|
throw new Error("bundle patch not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isV2){
|
if (UpdateContext.DEBUG) {
|
||||||
copyFromResourceV2(copiesv2List);
|
Log.d("react-native-update", "copyList size: " + copyList.size() + ", copiesMap size: " + copiesMap.size());
|
||||||
}else{
|
for (String from : copyList.keySet()) {
|
||||||
copyFromResource(copyList);
|
Log.d("react-native-update", "copyList entry: " + from + " -> " + copyList.get(from).size() + " targets");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
copyFromResource(copyList, copiesMap);
|
||||||
|
|
||||||
if (UpdateContext.DEBUG) {
|
if (UpdateContext.DEBUG) {
|
||||||
Log.d("react-native-update", "Unzip finished");
|
Log.d("react-native-update", "Unzip finished");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,9 +66,8 @@ public class SafeZipFile extends ZipFile {
|
|||||||
throw new SecurityException("Illegal name: " + name);
|
throw new SecurityException("Illegal name: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UpdateContext.DEBUG) {
|
|
||||||
Log.d("RNUpdate", "Unzipping " + name);
|
Log.d("react-native-update", "Unzipping " + name);
|
||||||
}
|
|
||||||
|
|
||||||
if (ze.isDirectory()) {
|
if (ze.isDirectory()) {
|
||||||
target.mkdirs();
|
target.mkdirs();
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class UpdateContext {
|
|||||||
private File rootDir;
|
private File rootDir;
|
||||||
private Executor executor;
|
private Executor executor;
|
||||||
|
|
||||||
public static boolean DEBUG = false;
|
public static boolean DEBUG = true;
|
||||||
private static ReactInstanceManager mReactInstanceManager;
|
private static ReactInstanceManager mReactInstanceManager;
|
||||||
private static boolean isUsingBundleUrl = false;
|
private static boolean isUsingBundleUrl = false;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-native-update",
|
"name": "react-native-update",
|
||||||
"version": "10.35.8",
|
"version": "10.36.0",
|
||||||
"description": "react-native hot update",
|
"description": "react-native hot update",
|
||||||
"main": "src/index",
|
"main": "src/index",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Reference in New Issue
Block a user