Fix IllegalArgumentException when dismissing ReactModalHostView

Summary: This diff fixes an IllegalArgumentException when dismissing ReactModalHostView. I wasn't able to reproduce this error because this is likely created by a race condition.

Reviewed By: axe-fb

Differential Revision: D12916787

fbshipit-source-id: b071ffc4c251f2a613bb1270de005def56818376
This commit is contained in:
David Vacca 2018-11-07 18:28:47 -08:00 committed by Facebook Github Bot
parent bccc4548e4
commit e57ad4ee37
4 changed files with 45 additions and 3 deletions

View File

@ -4,6 +4,7 @@ rn_android_library(
name = "common",
srcs = glob(["*.java"]),
provided_deps = [
react_native_dep("third-party/java/jsr-305:jsr-305"),
react_native_dep("third-party/android/support/v4:lib-support-v4"),
],
visibility = [

View File

@ -0,0 +1,37 @@
package com.facebook.react.views.common;
import android.content.Context;
import android.content.ContextWrapper;
import javax.annotation.Nullable;
/**
* Class containing static methods involving manipulations of Contexts and their related subclasses.
*/
public class ContextUtils {
/**
* Returns the nearest context in the chain (as defined by ContextWrapper.getBaseContext()) which
* is an instance of the specified type, or null if one could not be found
*
* @param context Initial context
* @param clazz Class instance to look for
* @param <T>
* @return the first context which is an instance of the specified class, or null if none exists
*/
public static @Nullable <T> T findContextOfType(
@Nullable Context context, Class<? extends T> clazz) {
while (!(clazz.isInstance(context))) {
if (context instanceof ContextWrapper) {
Context baseContext = ((ContextWrapper) context).getBaseContext();
if (context == baseContext) {
return null;
} else {
context = baseContext;
}
} else {
return null;
}
}
return (T) context;
}
}

View File

@ -17,6 +17,7 @@ rn_android_library(
react_native_target("java/com/facebook/react/touch:touch"),
react_native_target("java/com/facebook/react/uimanager:uimanager"),
react_native_target("java/com/facebook/react/uimanager/annotations:annotations"),
react_native_target("java/com/facebook/react/views/common:common"),
react_native_target("java/com/facebook/react/views/view:view"),
react_native_target("res:modal"),
],

View File

@ -28,6 +28,7 @@ import com.facebook.react.uimanager.JSTouchDispatcher;
import com.facebook.react.uimanager.RootView;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.views.common.ContextUtils;
import com.facebook.react.views.view.ReactViewGroup;
import java.util.ArrayList;
import javax.annotation.Nullable;
@ -123,9 +124,11 @@ public class ReactModalHostView extends ViewGroup implements LifecycleEventListe
private void dismiss() {
if (mDialog != null) {
Activity currentActivity = getCurrentActivity();
if (mDialog.isShowing() && (currentActivity == null || !currentActivity.isFinishing())) {
mDialog.dismiss();
if (mDialog.isShowing()) {
Activity dialogContext = ContextUtils.findContextOfType(mDialog.getContext(), Activity.class);
if (dialogContext == null || !dialogContext.isFinishing()) {
mDialog.dismiss();
}
}
mDialog = null;