diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java b/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java index f0989641c..26a956656 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactActivityDelegate.java @@ -15,9 +15,10 @@ import android.view.KeyEvent; import com.facebook.infer.annotation.Assertions; import com.facebook.react.bridge.Callback; +import com.facebook.react.devsupport.DoubleTapReloadRecognizer; +import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; import com.facebook.react.modules.core.PermissionListener; -import com.facebook.react.uimanager.RootView; import javax.annotation.Nullable; /** @@ -30,10 +31,10 @@ public class ReactActivityDelegate { private final @Nullable Activity mActivity; private final @Nullable String mMainComponentName; + private @Nullable ReactRootView mReactRootView; + private @Nullable DoubleTapReloadRecognizer mDoubleTapReloadRecognizer; private @Nullable PermissionListener mPermissionListener; private @Nullable Callback mPermissionsCallback; - private ReactDelegate mReactDelegate; - @Deprecated public ReactActivityDelegate(Activity activity, @Nullable String mainComponentName) { @@ -51,7 +52,7 @@ public class ReactActivityDelegate { } protected ReactRootView createRootView() { - return mReactDelegate.createRootView(); + return new ReactRootView(getContext()); } /** @@ -66,7 +67,7 @@ public class ReactActivityDelegate { } public ReactInstanceManager getReactInstanceManager() { - return mReactDelegate.getReactInstanceManager(); + return getReactNativeHost().getReactInstanceManager(); } public String getMainComponentName() { @@ -75,24 +76,36 @@ public class ReactActivityDelegate { protected void onCreate(Bundle savedInstanceState) { String mainComponentName = getMainComponentName(); - mReactDelegate = new ReactDelegate(getPlainActivity(), getReactNativeHost(), mainComponentName, getLaunchOptions()); - if (mMainComponentName != null) { - mReactDelegate.loadApp(); - getPlainActivity().setContentView(mReactDelegate.getReactRootView()); + if (mainComponentName != null) { + loadApp(mainComponentName); } + mDoubleTapReloadRecognizer = new DoubleTapReloadRecognizer(); } protected void loadApp(String appKey) { - mReactDelegate.loadApp(appKey); - getPlainActivity().setContentView(mReactDelegate.getReactRootView()); + if (mReactRootView != null) { + throw new IllegalStateException("Cannot loadApp while app is already running."); + } + mReactRootView = createRootView(); + mReactRootView.startReactApplication( + getReactNativeHost().getReactInstanceManager(), + appKey, + getLaunchOptions()); + getPlainActivity().setContentView(mReactRootView); } protected void onPause() { - mReactDelegate.onHostPause(); + if (getReactNativeHost().hasInstance()) { + getReactNativeHost().getReactInstanceManager().onHostPause(getPlainActivity()); + } } protected void onResume() { - mReactDelegate.onHostResume(); + if (getReactNativeHost().hasInstance()) { + getReactNativeHost().getReactInstanceManager().onHostResume( + getPlainActivity(), + (DefaultHardwareBackBtnHandler) getPlainActivity()); + } if (mPermissionsCallback != null) { mPermissionsCallback.invoke(); @@ -101,11 +114,20 @@ public class ReactActivityDelegate { } protected void onDestroy() { - mReactDelegate.onHostDestroy(); + if (mReactRootView != null) { + mReactRootView.unmountReactApplication(); + mReactRootView = null; + } + if (getReactNativeHost().hasInstance()) { + getReactNativeHost().getReactInstanceManager().onHostDestroy(getPlainActivity()); + } } public void onActivityResult(int requestCode, int resultCode, Intent data) { - mReactDelegate.onActivityResult(requestCode, resultCode, data, true); + if (getReactNativeHost().hasInstance()) { + getReactNativeHost().getReactInstanceManager() + .onActivityResult(getPlainActivity(), requestCode, resultCode, data); + } } public boolean onKeyDown(int keyCode, KeyEvent event) { @@ -119,7 +141,19 @@ public class ReactActivityDelegate { } public boolean onKeyUp(int keyCode, KeyEvent event) { - return mReactDelegate.shouldShowDevMenuOrReload(keyCode, event); + if (getReactNativeHost().hasInstance() && getReactNativeHost().getUseDeveloperSupport()) { + if (keyCode == KeyEvent.KEYCODE_MENU) { + getReactNativeHost().getReactInstanceManager().showDevOptionsDialog(); + return true; + } + boolean didDoubleTapR = Assertions.assertNotNull(mDoubleTapReloadRecognizer) + .didDoubleTapR(keyCode, getPlainActivity().getCurrentFocus()); + if (didDoubleTapR) { + getReactNativeHost().getReactInstanceManager().getDevSupportManager().handleReloadJS(); + return true; + } + } + return false; } public boolean onKeyLongPress(int keyCode, KeyEvent event) { @@ -133,7 +167,11 @@ public class ReactActivityDelegate { } public boolean onBackPressed() { - return mReactDelegate.onBackPressed(); + if (getReactNativeHost().hasInstance()) { + getReactNativeHost().getReactInstanceManager().onBackPressed(); + return true; + } + return false; } public boolean onNewIntent(Intent intent) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactDelegate.java b/ReactAndroid/src/main/java/com/facebook/react/ReactDelegate.java deleted file mode 100644 index e219c8be3..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactDelegate.java +++ /dev/null @@ -1,147 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.view.KeyEvent; - -import com.facebook.infer.annotation.Assertions; -import com.facebook.react.devsupport.DoubleTapReloadRecognizer; -import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; - -import javax.annotation.Nullable; - -/** - * A delegate for handling React Application support. This delegate is unaware whether it is used in - * an {@link Activity} or a {@link android.app.Fragment}. - */ -public class ReactDelegate { - - private final Activity mActivity; - private ReactRootView mReactRootView; - - @Nullable - private final String mMainComponentName; - - @Nullable - private Bundle mLaunchOptions; - - @Nullable - private DoubleTapReloadRecognizer mDoubleTapReloadRecognizer; - - private ReactNativeHost mReactNativeHost; - - - public ReactDelegate(Activity activity, ReactNativeHost reactNativeHost, @Nullable String appKey, @Nullable Bundle launchOptions) { - mActivity = activity; - mMainComponentName = appKey; - mLaunchOptions = launchOptions; - mDoubleTapReloadRecognizer = new DoubleTapReloadRecognizer(); - mReactNativeHost = reactNativeHost; - } - - public void onHostResume() { - if (getReactNativeHost().hasInstance()) { - if (mActivity instanceof DefaultHardwareBackBtnHandler) { - getReactNativeHost().getReactInstanceManager().onHostResume(mActivity, (DefaultHardwareBackBtnHandler) mActivity); - } else { - throw new ClassCastException("Host Activity does not implement DefaultHardwareBackBtnHandler"); - } - } - } - - public void onHostPause() { - if (getReactNativeHost().hasInstance()) { - getReactNativeHost().getReactInstanceManager().onHostPause(mActivity); - } - } - - public void onHostDestroy() { - if (mReactRootView != null) { - mReactRootView.unmountReactApplication(); - mReactRootView = null; - } - if (getReactNativeHost().hasInstance()) { - getReactNativeHost().getReactInstanceManager().onHostDestroy(mActivity); - } - } - - public boolean onBackPressed() { - if (getReactNativeHost().hasInstance()) { - getReactNativeHost().getReactInstanceManager().onBackPressed(); - return true; - } - return false; - } - - public void onActivityResult(int requestCode, int resultCode, Intent data, boolean shouldForwardToReactInstance) { - if (getReactNativeHost().hasInstance() && shouldForwardToReactInstance) { - getReactNativeHost().getReactInstanceManager().onActivityResult(mActivity, requestCode, resultCode, data); - } - } - - public void loadApp() { - loadApp(mMainComponentName); - } - - public void loadApp(String appKey) { - if (mReactRootView != null) { - throw new IllegalStateException("Cannot loadApp while app is already running."); - } - mReactRootView = createRootView(); - mReactRootView.startReactApplication( - getReactNativeHost().getReactInstanceManager(), - appKey, - mLaunchOptions); - - } - - public ReactRootView getReactRootView() { - return mReactRootView; - } - - - protected ReactRootView createRootView() { - return new ReactRootView(mActivity); - } - - /** - * Handles delegating the {@link Activity#onKeyUp(int, KeyEvent)} method to determine whether - * the application should show the developer menu or should reload the React Application. - * - * @return true if we consume the event and either shoed the develop menu or reloaded the application. - */ - public boolean shouldShowDevMenuOrReload(int keyCode, KeyEvent event) { - if (getReactNativeHost().hasInstance() && getReactNativeHost().getUseDeveloperSupport()) { - if (keyCode == KeyEvent.KEYCODE_MENU) { - getReactNativeHost().getReactInstanceManager().showDevOptionsDialog(); - return true; - } - boolean didDoubleTapR = Assertions.assertNotNull(mDoubleTapReloadRecognizer).didDoubleTapR(keyCode, mActivity.getCurrentFocus()); - if (didDoubleTapR) { - getReactNativeHost().getReactInstanceManager().getDevSupportManager().handleReloadJS(); - return true; - } - } - return false; - } - - /** - * Get the {@link ReactNativeHost} used by this app. - */ - private ReactNativeHost getReactNativeHost() { - return mReactNativeHost; - } - - public ReactInstanceManager getReactInstanceManager() { - return getReactNativeHost().getReactInstanceManager(); - } - -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactFragment.java b/ReactAndroid/src/main/java/com/facebook/react/ReactFragment.java deleted file mode 100644 index c4341d956..000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactFragment.java +++ /dev/null @@ -1,209 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react; - -import android.annotation.TargetApi; -import android.app.Activity; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.facebook.react.modules.core.PermissionAwareActivity; -import com.facebook.react.modules.core.PermissionListener; - -import javax.annotation.Nullable; - -import androidx.fragment.app.Fragment; - -/** - * Fragment for creating a React View. This allows the developer to "embed" a React Application - * inside native components such as a Drawer, ViewPager, etc. - */ -public class ReactFragment extends Fragment implements PermissionAwareActivity { - - private static final String ARG_COMPONENT_NAME = "arg_component_name"; - private static final String ARG_LAUNCH_OPTIONS = "arg_launch_options"; - - private ReactDelegate mReactDelegate; - - @Nullable - private PermissionListener mPermissionListener; - - - public ReactFragment() { - // Required empty public constructor - } - - /** - * @param componentName The name of the react native component - * @return A new instance of fragment ReactFragment. - */ - private static ReactFragment newInstance(String componentName, Bundle launchOptions) { - ReactFragment fragment = new ReactFragment(); - Bundle args = new Bundle(); - args.putString(ARG_COMPONENT_NAME, componentName); - args.putBundle(ARG_LAUNCH_OPTIONS, launchOptions); - fragment.setArguments(args); - return fragment; - } - - // region Lifecycle - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - String mainComponentName = null; - Bundle launchOptions = null; - if (getArguments() != null) { - mainComponentName = getArguments().getString(ARG_COMPONENT_NAME); - launchOptions = getArguments().getBundle(ARG_LAUNCH_OPTIONS); - } - if (mainComponentName == null) { - throw new IllegalStateException("Cannot loadApp if component name is null"); - } - mReactDelegate = new ReactDelegate(getActivity(), getReactNativeHost(), mainComponentName, launchOptions); - } - - /** - * Get the {@link ReactNativeHost} used by this app. By default, assumes - * {@link Activity#getApplication()} is an instance of {@link ReactApplication} and calls - * {@link ReactApplication#getReactNativeHost()}. Override this method if your application class - * does not implement {@code ReactApplication} or you simply have a different mechanism for - * storing a {@code ReactNativeHost}, e.g. as a static field somewhere. - */ - protected ReactNativeHost getReactNativeHost() { - return ((ReactApplication) getActivity().getApplication()).getReactNativeHost(); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - mReactDelegate.loadApp(); - return mReactDelegate.getReactRootView(); - } - - @Override - public void onResume() { - super.onResume(); - mReactDelegate.onHostResume(); - } - - @Override - public void onPause() { - super.onPause(); - mReactDelegate.onHostPause(); - } - - @Override - public void onDestroy() { - super.onDestroy(); - mReactDelegate.onHostDestroy(); - } - // endregion - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - mReactDelegate.onActivityResult(requestCode, resultCode, data, false); - } - - /** - * Helper to forward hardware back presses to our React Native Host - * - * This must be called via a forward from your host Activity - * - */ - public boolean onBackPressed() { - return mReactDelegate.onBackPressed(); - } - - /** - * Helper to forward onKeyUp commands from our host Activity. - * This allows ReactFragment to handle double tap reloads and dev menus - * - * This must be called via a forward from your host Activity - * - * @param keyCode keyCode - * @param event event - * @return true if we handled onKeyUp - */ - public boolean onKeyUp(int keyCode, KeyEvent event) { - return mReactDelegate.shouldShowDevMenuOrReload(keyCode, event); - } - - @Override - public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - if (mPermissionListener != null && - mPermissionListener.onRequestPermissionsResult(requestCode, permissions, grantResults)) { - mPermissionListener = null; - } - } - - @Override - public int checkPermission(String permission, int pid, int uid) { - return getActivity().checkPermission(permission, pid, uid); - } - - @TargetApi(Build.VERSION_CODES.M) - @Override - public int checkSelfPermission(String permission) { - return getActivity().checkSelfPermission(permission); - } - - @TargetApi(Build.VERSION_CODES.M) - @Override - public void requestPermissions(String[] permissions, int requestCode, PermissionListener listener) { - mPermissionListener = listener; - requestPermissions(permissions, requestCode); - } - - /** - * Builder class to help instantiate a ReactFragment - */ - public static class Builder { - - String mComponentName; - Bundle mLaunchOptions; - - public Builder() { - mComponentName = null; - mLaunchOptions = null; - } - - /** - * Set the Component name for our React Native instance. - * - * @param componentName The name of the component - * @return Builder - */ - public Builder setComponentName(String componentName) { - mComponentName = componentName; - return this; - } - - /** - * Set the Launch Options for our React Native instance. - * - * @param launchOptions launchOptions - * @return Builder - */ - public Builder setLaunchOptions(Bundle launchOptions) { - mLaunchOptions = launchOptions; - return this; - } - - public ReactFragment build() { - return ReactFragment.newInstance(mComponentName, mLaunchOptions); - } - - } -}