Skip to content

Commit 8bc6527

Browse files
committed
fix restart
1 parent ef34404 commit 8bc6527

1 file changed

Lines changed: 88 additions & 40 deletions

File tree

android/src/main/java/cn/reactnative/modules/update/UpdateModuleImpl.java

Lines changed: 88 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,78 @@ private static String getDefaultBundleAssetName(Context application) {
8383
return bundleAssetName;
8484
}
8585

86+
private static String toAssetUrl(String bundleAssetName) {
87+
if (bundleAssetName == null || bundleAssetName.isEmpty()) {
88+
return "assets://index.android.bundle";
89+
}
90+
if (bundleAssetName.startsWith("assets://")) {
91+
return bundleAssetName;
92+
}
93+
return "assets://" + bundleAssetName;
94+
}
95+
96+
private static JSBundleLoader createBundleLoader(Context application, String updateBundlePath, boolean loadAssetSynchronously) {
97+
if (updateBundlePath != null) {
98+
return JSBundleLoader.createFileLoader(updateBundlePath);
99+
}
100+
return JSBundleLoader.createAssetLoader(
101+
application,
102+
toAssetUrl(getDefaultBundleAssetName(application)),
103+
loadAssetSynchronously
104+
);
105+
}
106+
107+
private static Object getReactHost(Activity currentActivity, Context application) {
108+
if (currentActivity instanceof ReactActivity) {
109+
try {
110+
Method getReactDelegateMethod = ReactActivity.class.getMethod("getReactDelegate");
111+
ReactDelegate reactDelegate = (ReactDelegate) getReactDelegateMethod.invoke(currentActivity);
112+
if (reactDelegate != null) {
113+
Field reactHostField = getCompatibleField(reactDelegate.getClass(), "reactHost");
114+
reactHostField.setAccessible(true);
115+
Object reactHost = reactHostField.get(reactDelegate);
116+
if (reactHost != null) {
117+
return reactHost;
118+
}
119+
}
120+
} catch (Throwable ignored) {
121+
}
122+
}
123+
124+
try {
125+
Method getReactHostMethod = application.getClass().getMethod("getReactHost");
126+
return getReactHostMethod.invoke(application);
127+
} catch (Throwable ignored) {
128+
}
129+
130+
return null;
131+
}
132+
133+
private static void reloadReactHost(Object reactHost, JSBundleLoader loader) throws Throwable {
134+
try {
135+
Field devSupportField = getCompatibleField(reactHost.getClass(), "useDevSupport");
136+
devSupportField.setAccessible(true);
137+
devSupportField.set(reactHost, false);
138+
} catch (Throwable ignored) {
139+
}
140+
141+
Field reactHostDelegateField = getCompatibleField(reactHost.getClass(), "reactHostDelegate");
142+
reactHostDelegateField.setAccessible(true);
143+
Object reactHostDelegate = reactHostDelegateField.get(reactHost);
144+
145+
String bundleFieldName = "jsBundleLoader";
146+
if ("expo.modules.ExpoReactHostFactory.ExpoReactHostDelegate".equals(reactHostDelegate.getClass().getCanonicalName())) {
147+
bundleFieldName = "_jsBundleLoader";
148+
}
149+
150+
Field jsBundleLoaderField = reactHostDelegate.getClass().getDeclaredField(bundleFieldName);
151+
jsBundleLoaderField.setAccessible(true);
152+
jsBundleLoaderField.set(reactHostDelegate, loader);
153+
154+
Method reloadMethod = reactHost.getClass().getMethod("reload", String.class);
155+
reloadMethod.invoke(reactHost, "react-native-update");
156+
}
157+
86158
public static void downloadFullUpdate(UpdateContext updateContext, final ReadableMap options, final Promise promise) {
87159
String url = options.getString("updateUrl");
88160
String hash = options.getString("hash");
@@ -178,14 +250,20 @@ public void run() {
178250

179251
final Context application = mContext.getApplicationContext();
180252
String updateBundlePath = updateContext.getBundleUrl(application);
253+
final Activity currentActivity = mContext.getCurrentActivity();
181254

182-
JSBundleLoader loader;
183-
184-
if (updateBundlePath != null) {
185-
loader = JSBundleLoader.createFileLoader(updateBundlePath);
186-
} else {
187-
loader = JSBundleLoader.createAssetLoader(application, getDefaultBundleAssetName(application), false);
255+
Object reactHost = getReactHost(currentActivity, application);
256+
if (reactHost != null) {
257+
try {
258+
reloadReactHost(reactHost, createBundleLoader(application, updateBundlePath, true));
259+
promise.resolve(true);
260+
return;
261+
} catch (Throwable err) {
262+
Log.e(NAME, "Failed to reload via ReactHost", err);
263+
}
188264
}
265+
266+
JSBundleLoader loader = createBundleLoader(application, updateBundlePath, false);
189267
try {
190268
ReactInstanceManager instanceManager = updateContext.getCustomReactInstanceManager();
191269

@@ -207,46 +285,16 @@ public void run() {
207285
promise.resolve(true);
208286

209287
} catch (Throwable err) {
210-
final Activity currentActivity = mContext.getCurrentActivity();
211288
if (currentActivity == null) {
212289
promise.reject(err);
213290
return;
214291
}
215292
try {
216-
java.lang.reflect.Method getReactDelegateMethod =
217-
ReactActivity.class.getMethod("getReactDelegate");
218-
219-
ReactDelegate reactDelegate = (ReactDelegate)
220-
getReactDelegateMethod.invoke(currentActivity);
221-
222-
Field reactHostField = getCompatibleField(ReactDelegate.class, "reactHost");
223-
reactHostField.setAccessible(true);
224-
Object reactHost = reactHostField.get(reactDelegate);
225-
226-
Field devSupport = getCompatibleField(reactHost.getClass(), "useDevSupport");
227-
devSupport.setAccessible(true);
228-
devSupport.set(reactHost, false);
229-
230-
// Access the ReactHostDelegate field (compatible with mReactHostDelegate/reactHostDelegate)
231-
Field reactHostDelegateField = getCompatibleField(reactHost.getClass(), "reactHostDelegate");
232-
reactHostDelegateField.setAccessible(true);
233-
Object reactHostDelegate = reactHostDelegateField.get(reactHost);
234-
235-
String bundleFieldName = "jsBundleLoader";
236-
if (reactHostDelegate.getClass().getCanonicalName().equals("expo.modules.ExpoReactHostFactory.ExpoReactHostDelegate")) {
237-
bundleFieldName = "_jsBundleLoader";
293+
Object currentReactHost = getReactHost(currentActivity, application);
294+
if (currentReactHost == null) {
295+
throw err;
238296
}
239-
240-
// Modify the jsBundleLoader field
241-
Field jsBundleLoaderField = reactHostDelegate.getClass().getDeclaredField(bundleFieldName);
242-
jsBundleLoaderField.setAccessible(true);
243-
jsBundleLoaderField.set(reactHostDelegate, loader);
244-
245-
// Get the reload method with a String parameter
246-
java.lang.reflect.Method reloadMethod = reactHost.getClass().getMethod("reload", String.class);
247-
248-
// Invoke the reload method with a reason
249-
reloadMethod.invoke(reactHost, "react-native-update");
297+
reloadReactHost(currentReactHost, createBundleLoader(application, updateBundlePath, true));
250298
promise.resolve(true);
251299
} catch (Throwable e) {
252300
currentActivity.runOnUiThread(new Runnable() {

0 commit comments

Comments
 (0)