react-native-update 10.40.2 → 10.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README-CN.md +3 -3
- package/android/src/main/java/cn/reactnative/modules/update/BundledResourceCopier.java +58 -2
- package/android/src/main/java/cn/reactnative/modules/update/DownloadTask.java +17 -3
- package/package.json +1 -1
- package/{react-native-update-10.40.1.tgz → react-native-update-10.40.2.tgz} +0 -0
package/README-CN.md
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
### 区域服务说明
|
|
8
8
|
|
|
9
|
-
- 中国区服务使用 **Pushy**(<https://pushy.reactnative.cn
|
|
10
|
-
- 全球区服务使用 **Cresc**(<https://cresc.dev>),由 **CHARMLOT PTE. LTD.**
|
|
11
|
-
-
|
|
9
|
+
- 中国区服务使用 **Pushy**(<https://pushy.reactnative.cn>),由**武汉青罗网络科技有限公司**运营,服务器位于中国境内,也通过 cloudflare 智能分流,完全支持海外用户高速访问。**使用人民币支付订阅**。
|
|
10
|
+
- 全球区服务使用 **Cresc**(<https://cresc.dev>),由 **CHARMLOT PTE. LTD.** 运营,服务器位于新加坡。**使用美元支付订阅**。
|
|
11
|
+
- 中国区与全球区服务由不同公司实体独立运营,服务器、数据及控制台系统彼此隔离。如果可以使用网银和支付宝结算,建议使用 Pushy,否则建议使用 Cresc。
|
|
12
12
|
|
|
13
13
|
**现已支持鸿蒙以及新架构**
|
|
14
14
|
|
|
@@ -33,15 +33,36 @@ final class BundledResourceCopier {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
// Holds the exact archive a CRC32 match came from, so the fallback copy
|
|
37
|
+
// reads from that archive even if another APK exposes the same entry name
|
|
38
|
+
// with different bytes.
|
|
39
|
+
private static final class ZipSource {
|
|
40
|
+
final ZipEntry entry;
|
|
41
|
+
final SafeZipFile zipFile;
|
|
42
|
+
|
|
43
|
+
ZipSource(ZipEntry entry, SafeZipFile zipFile) {
|
|
44
|
+
this.entry = entry;
|
|
45
|
+
this.zipFile = zipFile;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
36
49
|
BundledResourceCopier(Context context) {
|
|
37
50
|
this.context = context.getApplicationContext();
|
|
38
51
|
}
|
|
39
52
|
|
|
40
|
-
void copyFromResource(
|
|
53
|
+
void copyFromResource(
|
|
54
|
+
HashMap<String, ArrayList<File>> resToCopy,
|
|
55
|
+
HashMap<String, Long> crcByFrom
|
|
56
|
+
) throws IOException {
|
|
41
57
|
ArrayList<String> apkPaths = collectApkPaths();
|
|
42
58
|
HashMap<String, ZipEntry> availableEntries = new HashMap<String, ZipEntry>();
|
|
43
59
|
HashMap<String, SafeZipFile> zipFileMap = new HashMap<String, SafeZipFile>();
|
|
44
60
|
HashMap<String, SafeZipFile> entryToZipFileMap = new HashMap<String, SafeZipFile>();
|
|
61
|
+
// Content checksum index: CRC32 -> matched archive source. Lets us
|
|
62
|
+
// locate a file by content when its origin path is not present verbatim
|
|
63
|
+
// on device (e.g. APK baseline diff applied on an AAB/split-apk install
|
|
64
|
+
// whose res/ paths were shortened). First entry for a given crc wins.
|
|
65
|
+
HashMap<Long, ZipSource> crcToEntry = new HashMap<Long, ZipSource>();
|
|
45
66
|
|
|
46
67
|
try {
|
|
47
68
|
for (String apkPath : apkPaths) {
|
|
@@ -55,6 +76,10 @@ final class BundledResourceCopier {
|
|
|
55
76
|
availableEntries.put(entryName, ze);
|
|
56
77
|
entryToZipFileMap.put(entryName, zipFile);
|
|
57
78
|
}
|
|
79
|
+
long crc = ze.getCrc();
|
|
80
|
+
if (crc != -1L && !crcToEntry.containsKey(crc)) {
|
|
81
|
+
crcToEntry.put(crc, new ZipSource(ze, zipFile));
|
|
82
|
+
}
|
|
58
83
|
}
|
|
59
84
|
}
|
|
60
85
|
|
|
@@ -76,6 +101,7 @@ final class BundledResourceCopier {
|
|
|
76
101
|
|
|
77
102
|
ZipEntry entry = availableEntries.get(fromPath);
|
|
78
103
|
String actualSourcePath = fromPath;
|
|
104
|
+
SafeZipFile matchedZipFile = null;
|
|
79
105
|
ResolvedResourceSource resolvedResource = null;
|
|
80
106
|
|
|
81
107
|
if (entry == null) {
|
|
@@ -87,10 +113,35 @@ final class BundledResourceCopier {
|
|
|
87
113
|
}
|
|
88
114
|
}
|
|
89
115
|
|
|
116
|
+
// Content (CRC32) match: robust across APK/AAB packaging because
|
|
117
|
+
// the checksum is over the uncompressed file content, not its
|
|
118
|
+
// path. Preferred over the resource-id heuristic below.
|
|
119
|
+
if (entry == null && crcByFrom != null) {
|
|
120
|
+
Long wantedCrc = crcByFrom.get(fromPath);
|
|
121
|
+
if (wantedCrc != null) {
|
|
122
|
+
ZipSource matched = crcToEntry.get(wantedCrc);
|
|
123
|
+
if (matched != null) {
|
|
124
|
+
entry = matched.entry;
|
|
125
|
+
matchedZipFile = matched.zipFile;
|
|
126
|
+
actualSourcePath = matched.entry.getName();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
90
131
|
if (entry == null) {
|
|
91
132
|
resolvedResource = resolveBundledResource(fromPath);
|
|
92
133
|
if (resolvedResource != null) {
|
|
93
134
|
actualSourcePath = resolvedResource.assetPath;
|
|
135
|
+
// resolveBundledResource resolved the density-correct
|
|
136
|
+
// file path; copy that exact entry from the already-open
|
|
137
|
+
// archives so the right variant is used. (openRawResource
|
|
138
|
+
// would re-resolve the id at the current configuration
|
|
139
|
+
// density and ignore the requested one.)
|
|
140
|
+
ZipEntry resolvedEntry = availableEntries.get(actualSourcePath);
|
|
141
|
+
if (resolvedEntry != null) {
|
|
142
|
+
entry = resolvedEntry;
|
|
143
|
+
resolvedResource = null;
|
|
144
|
+
}
|
|
94
145
|
}
|
|
95
146
|
}
|
|
96
147
|
|
|
@@ -104,7 +155,9 @@ final class BundledResourceCopier {
|
|
|
104
155
|
if (lastTarget != null) {
|
|
105
156
|
UpdateFileUtils.copyFile(lastTarget, target);
|
|
106
157
|
} else if (entry != null) {
|
|
107
|
-
SafeZipFile sourceZipFile =
|
|
158
|
+
SafeZipFile sourceZipFile = matchedZipFile != null
|
|
159
|
+
? matchedZipFile
|
|
160
|
+
: entryToZipFileMap.get(actualSourcePath);
|
|
108
161
|
if (sourceZipFile == null) {
|
|
109
162
|
sourceZipFile = baseZipFile;
|
|
110
163
|
}
|
|
@@ -247,6 +300,9 @@ final class BundledResourceCopier {
|
|
|
247
300
|
}
|
|
248
301
|
|
|
249
302
|
private InputStream openResolvedResourceStream(ResolvedResourceSource source) throws IOException {
|
|
303
|
+
// Defensive fallback only: reached when the density-resolved assetPath
|
|
304
|
+
// is not present as a zip entry in any loaded APK. Best-effort, resolves
|
|
305
|
+
// at the current configuration density.
|
|
250
306
|
try {
|
|
251
307
|
return context.getResources().openRawResource(source.resourceId);
|
|
252
308
|
} catch (Resources.NotFoundException e) {
|
|
@@ -40,6 +40,11 @@ class DownloadTask implements Runnable {
|
|
|
40
40
|
final ArrayList<String> copyFroms = new ArrayList<String>();
|
|
41
41
|
final ArrayList<String> copyTos = new ArrayList<String>();
|
|
42
42
|
final ArrayList<String> deletes = new ArrayList<String>();
|
|
43
|
+
// Maps a copy source path ("from") to the CRC32 of the file content,
|
|
44
|
+
// when provided by the manifest ("copiesCrc"). Lets the resource
|
|
45
|
+
// copier locate the file by content if the path is not present on
|
|
46
|
+
// device (APK baseline -> AAB install path shortening).
|
|
47
|
+
final HashMap<String, Long> copyCrcs = new HashMap<String, Long>();
|
|
43
48
|
}
|
|
44
49
|
|
|
45
50
|
private final Context context;
|
|
@@ -140,8 +145,11 @@ class DownloadTask implements Runnable {
|
|
|
140
145
|
JSONObject manifest,
|
|
141
146
|
ArrayList<String> copyFroms,
|
|
142
147
|
ArrayList<String> copyTos,
|
|
143
|
-
ArrayList<String> deletes
|
|
148
|
+
ArrayList<String> deletes,
|
|
149
|
+
HashMap<String, Long> copyCrcs
|
|
144
150
|
) throws JSONException {
|
|
151
|
+
JSONObject copiesCrc = manifest.optJSONObject("copiesCrc");
|
|
152
|
+
|
|
145
153
|
JSONObject copies = manifest.optJSONObject("copies");
|
|
146
154
|
if (copies != null) {
|
|
147
155
|
Iterator<?> keys = copies.keys();
|
|
@@ -153,6 +161,11 @@ class DownloadTask implements Runnable {
|
|
|
153
161
|
}
|
|
154
162
|
copyFroms.add(from);
|
|
155
163
|
copyTos.add(to);
|
|
164
|
+
if (copiesCrc != null && copyCrcs != null && copiesCrc.has(to)) {
|
|
165
|
+
// Same content => same crc, so grouping multiple "to" under
|
|
166
|
+
// one "from" stays consistent.
|
|
167
|
+
copyCrcs.put(from, copiesCrc.getLong(to));
|
|
168
|
+
}
|
|
156
169
|
}
|
|
157
170
|
}
|
|
158
171
|
|
|
@@ -220,7 +233,8 @@ class DownloadTask implements Runnable {
|
|
|
220
233
|
manifest,
|
|
221
234
|
contents.copyFroms,
|
|
222
235
|
contents.copyTos,
|
|
223
|
-
contents.deletes
|
|
236
|
+
contents.deletes,
|
|
237
|
+
contents.copyCrcs
|
|
224
238
|
);
|
|
225
239
|
continue;
|
|
226
240
|
}
|
|
@@ -285,7 +299,7 @@ class DownloadTask implements Runnable {
|
|
|
285
299
|
originBundleFile.delete();
|
|
286
300
|
}
|
|
287
301
|
|
|
288
|
-
bundledResourceCopier.copyFromResource(copyList);
|
|
302
|
+
bundledResourceCopier.copyFromResource(copyList, contents.copyCrcs);
|
|
289
303
|
}
|
|
290
304
|
|
|
291
305
|
private void doPatchFromPpk() throws IOException, JSONException {
|
package/package.json
CHANGED
|
index 3ad9f0d..39a9991 100644
|
|
|
Binary file
|