mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-01-12 22:50:10 +08:00
Back out "[react-native][PR] Android - Add a ReactFragment"
Summary: Original commit changeset: b50b708cde45 Reviewed By: mdvacca Differential Revision: D14792438 fbshipit-source-id: c5e0b5f7663fe70110f73ae94a6fa99388f87ae3
This commit is contained in:
committed by
Facebook Github Bot
parent
0f909e3318
commit
7944d47a63
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user