react-native-update 10.37.0 → 10.37.1
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.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
### 优势
|
|
12
12
|
|
|
13
13
|
1. 对中国用户使用阿里云高速 CDN 分发,对比其他服务器在国外的热更新服务,分发更稳定,更新成功率极高。对国外用户则智能分流至 cloudflare,同样享受高速更新服务。
|
|
14
|
-
2. 基于 bsdiff/hdiff
|
|
14
|
+
2. 基于 bsdiff/hdiff 算法创建的**超小更新包**,通常版本迭代后在几十至几百 KB 级别(其他全量热更新服务所需流量通常在几十 MB 级别)。
|
|
15
15
|
3. 始终跟进 RN 最新正式版本,第一时间提供支持。支持 hermes 字节码格式。支持新架构(注:安卓 0.73.0 ~ 0.76.0 的新架构因官方 bug 不支持,0.73 以下或 0.76.1 以上的新架构可用)。
|
|
16
16
|
4. 跨越多个版本进行更新时,只需要下载**一个更新包**,不需要逐版本依次更新。
|
|
17
17
|
5. 命令行工具 & 网页双端管理,版本发布过程简单便捷,完全可以集成 CI。
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
| 对比维度 | react-native-update | expo-update | react-native-code-push |
|
|
25
25
|
|---------|---------------------|-------------|------------------------|
|
|
26
26
|
| **价格/成本** | 提供免费额度,多级梯度付费(最低约 66 元/月),流量不单独计费 | 提供免费额度,多级梯度付费(最低约 136 元/月),超出流量额外计费 | ❌ **已停运**(Microsoft App Center 已于 2025 年 3 月 31 日停止服务) |
|
|
27
|
-
| **更新包大小** | ⭐⭐⭐⭐⭐
|
|
27
|
+
| **更新包大小** | ⭐⭐⭐⭐⭐ 几十至几百 KB(增量更新) | ⭐⭐⭐ 全量更新(通常几十 MB) | ❌ **已停运** |
|
|
28
28
|
| **中国地区访问速度** | ⭐⭐⭐⭐⭐ 阿里云 CDN,速度极快 | ⭐⭐ 国外服务器,可能较慢 | ❌ **已停运** |
|
|
29
29
|
| **iOS 支持** | ✅ 支持 | ✅ 支持 | ❌ **已停运** |
|
|
30
30
|
| **Android 支持** | ✅ 支持 | ✅ 支持 | ❌ **已停运** |
|
|
@@ -134,13 +134,21 @@ public class UpdateModuleImpl {
|
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
public static void reloadUpdate(final UpdateContext updateContext,final ReactApplicationContext mContext, final ReadableMap options, final Promise promise) {
|
|
137
|
+
public static void reloadUpdate(final UpdateContext updateContext, final ReactApplicationContext mContext, final ReadableMap options, final Promise promise) {
|
|
138
138
|
final String hash = options.getString("hash");
|
|
139
|
+
restartApp(updateContext, mContext, hash, promise);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
public static void restartApp(final UpdateContext updateContext, final ReactApplicationContext mContext, final String hash, final Promise promise) {
|
|
139
144
|
UiThreadUtil.runOnUiThread(new Runnable() {
|
|
140
145
|
@Override
|
|
141
146
|
public void run() {
|
|
142
|
-
|
|
143
|
-
|
|
147
|
+
// 如果提供了 hash,则切换版本
|
|
148
|
+
if (hash != null && updateContext != null) {
|
|
149
|
+
updateContext.switchVersion(hash);
|
|
150
|
+
}
|
|
151
|
+
|
|
144
152
|
final Context application = mContext.getApplicationContext();
|
|
145
153
|
JSBundleLoader loader = JSBundleLoader.createFileLoader(UpdateContext.getBundleUrl(application));
|
|
146
154
|
try {
|
|
@@ -166,6 +174,7 @@ public class UpdateModuleImpl {
|
|
|
166
174
|
} catch (Throwable err) {
|
|
167
175
|
final Activity currentActivity = mContext.getCurrentActivity();
|
|
168
176
|
if (currentActivity == null) {
|
|
177
|
+
promise.reject(err);
|
|
169
178
|
return;
|
|
170
179
|
}
|
|
171
180
|
try {
|
|
@@ -203,6 +212,7 @@ public class UpdateModuleImpl {
|
|
|
203
212
|
|
|
204
213
|
// Invoke the reload method with a reason
|
|
205
214
|
reloadMethod.invoke(reactHost, "react-native-update");
|
|
215
|
+
promise.resolve(true);
|
|
206
216
|
} catch (Throwable e) {
|
|
207
217
|
currentActivity.runOnUiThread(new Runnable() {
|
|
208
218
|
@Override
|
|
@@ -210,42 +220,17 @@ public class UpdateModuleImpl {
|
|
|
210
220
|
currentActivity.recreate();
|
|
211
221
|
}
|
|
212
222
|
});
|
|
223
|
+
promise.resolve(true);
|
|
213
224
|
}
|
|
214
225
|
}
|
|
215
|
-
promise.resolve(true);
|
|
216
226
|
}
|
|
217
227
|
});
|
|
218
228
|
}
|
|
219
229
|
|
|
230
|
+
|
|
220
231
|
public static void restartApp(final ReactApplicationContext mContext, final Promise promise) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
public void run() {
|
|
224
|
-
try {
|
|
225
|
-
final Context application = mContext.getApplicationContext();
|
|
226
|
-
ReactInstanceManager instanceManager = ((ReactApplication) application).getReactNativeHost().getReactInstanceManager();
|
|
227
|
-
|
|
228
|
-
instanceManager.recreateReactContextInBackground();
|
|
229
|
-
promise.resolve(true);
|
|
230
|
-
|
|
231
|
-
} catch (Throwable err) {
|
|
232
|
-
promise.reject("restartApp failed: "+err.getMessage());
|
|
233
|
-
Log.e("pushy", "restartApp failed", err);
|
|
234
|
-
|
|
235
|
-
final Activity currentActivity = mContext.getCurrentActivity();
|
|
236
|
-
if (currentActivity == null) {
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
currentActivity.runOnUiThread(new Runnable() {
|
|
240
|
-
@Override
|
|
241
|
-
public void run() {
|
|
242
|
-
currentActivity.recreate();
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
-
}
|
|
232
|
+
restartApp(null, mContext, null, promise);
|
|
233
|
+
}
|
|
249
234
|
|
|
250
235
|
public static void setNeedUpdate(final UpdateContext updateContext, final ReadableMap options, final Promise promise) {
|
|
251
236
|
final String hash = options.getString("hash");
|
|
@@ -320,3 +305,4 @@ public class UpdateModuleImpl {
|
|
|
320
305
|
}
|
|
321
306
|
|
|
322
307
|
}
|
|
308
|
+
|
|
@@ -104,27 +104,27 @@ public class UpdateModule extends NativePushySpec {
|
|
|
104
104
|
|
|
105
105
|
@Override
|
|
106
106
|
public void downloadPatchFromPpk(ReadableMap options, final Promise promise) {
|
|
107
|
-
UpdateModuleImpl.downloadPatchFromPpk(updateContext,options,promise);
|
|
107
|
+
UpdateModuleImpl.downloadPatchFromPpk(updateContext, options, promise);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
@Override
|
|
111
111
|
public void reloadUpdate(ReadableMap options,Promise promise) {
|
|
112
|
-
UpdateModuleImpl.reloadUpdate(updateContext, mContext, options,promise);
|
|
112
|
+
UpdateModuleImpl.reloadUpdate(updateContext, mContext, options, promise);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
@Override
|
|
116
116
|
public void restartApp(Promise promise) {
|
|
117
|
-
UpdateModuleImpl.restartApp(mContext, promise);
|
|
117
|
+
UpdateModuleImpl.restartApp(updateContext, mContext, null, promise);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
@Override
|
|
121
121
|
public void setNeedUpdate(ReadableMap options,Promise promise) {
|
|
122
|
-
UpdateModuleImpl.setNeedUpdate(updateContext, options,promise);
|
|
122
|
+
UpdateModuleImpl.setNeedUpdate(updateContext, options, promise);
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
@Override
|
|
126
126
|
public void markSuccess(Promise promise) {
|
|
127
|
-
UpdateModuleImpl.markSuccess(updateContext,promise);
|
|
127
|
+
UpdateModuleImpl.markSuccess(updateContext, promise);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
@Override
|
|
@@ -4,36 +4,31 @@ import path from 'path';
|
|
|
4
4
|
export function reactNativeUpdatePlugin() {
|
|
5
5
|
return {
|
|
6
6
|
pluginId: 'reactNativeUpdatePlugin',
|
|
7
|
-
apply(
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
'entry/src/main/resources/rawfile/meta.json',
|
|
15
|
-
);
|
|
16
|
-
fs.mkdirSync(path.dirname(metaFilePath), { recursive: true });
|
|
7
|
+
apply(_node) {
|
|
8
|
+
const cwd = process.cwd();
|
|
9
|
+
const metaFilePath = path.resolve(
|
|
10
|
+
cwd,
|
|
11
|
+
'entry/src/main/resources/rawfile/meta.json',
|
|
12
|
+
);
|
|
13
|
+
fs.mkdirSync(path.dirname(metaFilePath), { recursive: true });
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
15
|
+
const moduleJsonPath = path.resolve(cwd, 'AppScope/app.json5');
|
|
16
|
+
let versionName = '';
|
|
17
|
+
if (fs.existsSync(moduleJsonPath)) {
|
|
18
|
+
const content = fs.readFileSync(moduleJsonPath, 'utf-8');
|
|
19
|
+
const match = content.match(
|
|
20
|
+
/(?:"versionName"|versionName):\s*["']([^"']+)["']/,
|
|
21
|
+
);
|
|
22
|
+
versionName = match?.[1] || '';
|
|
23
|
+
}
|
|
27
24
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
const metaContent = {
|
|
26
|
+
pushy_build_time: new Date().toISOString(),
|
|
27
|
+
versionName,
|
|
28
|
+
};
|
|
32
29
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
},
|
|
36
|
-
});
|
|
30
|
+
fs.writeFileSync(metaFilePath, JSON.stringify(metaContent, null, 2));
|
|
31
|
+
console.log(`Build time written to ${metaFilePath}`);
|
|
37
32
|
},
|
|
38
33
|
};
|
|
39
34
|
}
|