mirror of
https://github.com/status-im/react-native.git
synced 2025-02-04 05:34:15 +00:00
Add ReactInstanceHolder
Reviewed By: astreet Differential Revision: D3328342 fbshipit-source-id: af4e825d0b7c2d3d4490094a939e97cc527dd242
This commit is contained in:
parent
d78602b8cd
commit
49f20f4154
@ -40,38 +40,8 @@ public abstract class ReactActivity extends Activity
|
||||
private @Nullable PermissionListener mPermissionListener;
|
||||
private @Nullable ReactInstanceManager mReactInstanceManager;
|
||||
private @Nullable ReactRootView mReactRootView;
|
||||
private LifecycleState mLifecycleState = LifecycleState.BEFORE_RESUME;
|
||||
private DoubleTapReloadRecognizer mDoubleTapReloadRecognizer;
|
||||
|
||||
/**
|
||||
* Returns the name of the bundle in assets. If this is null, and no file path is specified for
|
||||
* the bundle, the app will only work with {@code getUseDeveloperSupport} enabled and will
|
||||
* always try to load the JS bundle from the packager server.
|
||||
* e.g. "index.android.bundle"
|
||||
*/
|
||||
protected @Nullable String getBundleAssetName() {
|
||||
return "index.android.bundle";
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a custom path of the bundle file. This is used in cases the bundle should be loaded
|
||||
* from a custom path. By default it is loaded from Android assets, from a path specified
|
||||
* by {@link getBundleAssetName}.
|
||||
* e.g. "file://sdcard/myapp_cache/index.android.bundle"
|
||||
*/
|
||||
protected @Nullable String getJSBundleFile() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the main module. Determines the URL used to fetch the JS bundle
|
||||
* from the packager server. It is only used when dev support is enabled.
|
||||
* This is the first file to be executed once the {@link ReactInstanceManager} is created.
|
||||
* e.g. "index.android"
|
||||
*/
|
||||
protected String getJSMainModuleName() {
|
||||
return "index.android";
|
||||
}
|
||||
private boolean mDoRefresh = false;
|
||||
|
||||
/**
|
||||
* Returns the launchOptions which will be passed to the {@link ReactInstanceManager}
|
||||
@ -91,44 +61,6 @@ public abstract class ReactActivity extends Activity
|
||||
*/
|
||||
protected abstract String getMainComponentName();
|
||||
|
||||
/**
|
||||
* Returns whether dev mode should be enabled. This enables e.g. the dev menu.
|
||||
*/
|
||||
protected abstract boolean getUseDeveloperSupport();
|
||||
|
||||
/**
|
||||
* Returns a list of {@link ReactPackage} used by the app.
|
||||
* You'll most likely want to return at least the {@code MainReactPackage}.
|
||||
* If your app uses additional views or modules besides the default ones,
|
||||
* you'll want to include more packages here.
|
||||
*/
|
||||
protected abstract List<ReactPackage> getPackages();
|
||||
|
||||
/**
|
||||
* A subclass may override this method if it needs to use a custom instance.
|
||||
*/
|
||||
protected ReactInstanceManager createReactInstanceManager() {
|
||||
ReactInstanceManager.Builder builder = ReactInstanceManager.builder()
|
||||
.setApplication(getApplication())
|
||||
.setJSMainModuleName(getJSMainModuleName())
|
||||
.setUseDeveloperSupport(getUseDeveloperSupport())
|
||||
.setInitialLifecycleState(mLifecycleState);
|
||||
|
||||
for (ReactPackage reactPackage : getPackages()) {
|
||||
builder.addPackage(reactPackage);
|
||||
}
|
||||
|
||||
String jsBundleFile = getJSBundleFile();
|
||||
|
||||
if (jsBundleFile != null) {
|
||||
builder.setJSBundleFile(jsBundleFile);
|
||||
} else {
|
||||
builder.setBundleAssetName(getBundleAssetName());
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* A subclass may override this method if it needs to use a custom {@link ReactRootView}.
|
||||
*/
|
||||
@ -136,6 +68,27 @@ public abstract class ReactActivity extends Activity
|
||||
return new ReactRootView(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link ReactNativeHost} used by this app. By default, assumes {@link #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) getApplication()).getReactNativeHost();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether developer support should be enabled or not. By default this delegates to
|
||||
* {@link ReactNativeHost#getUseDeveloperSupport()}. Override this method if your application
|
||||
* class does not implement {@code ReactApplication} or you simply have a different logic for
|
||||
* determining this (default just checks {@code BuildConfig}).
|
||||
*/
|
||||
protected boolean getUseDeveloperSupport() {
|
||||
return ((ReactApplication) getApplication()).getReactNativeHost().getUseDeveloperSupport();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -150,9 +103,11 @@ public abstract class ReactActivity extends Activity
|
||||
}
|
||||
}
|
||||
|
||||
mReactInstanceManager = createReactInstanceManager();
|
||||
mReactRootView = createRootView();
|
||||
mReactRootView.startReactApplication(mReactInstanceManager, getMainComponentName(), getLaunchOptions());
|
||||
mReactRootView.startReactApplication(
|
||||
getReactNativeHost().getReactInstanceManager(),
|
||||
getMainComponentName(),
|
||||
getLaunchOptions());
|
||||
setContentView(mReactRootView);
|
||||
mDoubleTapReloadRecognizer = new DoubleTapReloadRecognizer();
|
||||
}
|
||||
@ -161,10 +116,8 @@ public abstract class ReactActivity extends Activity
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
mLifecycleState = LifecycleState.BEFORE_RESUME;
|
||||
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onHostPause();
|
||||
if (getReactNativeHost().hasInstance()) {
|
||||
getReactNativeHost().getReactInstanceManager().onHostPause();
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,10 +125,8 @@ public abstract class ReactActivity extends Activity
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
mLifecycleState = LifecycleState.RESUMED;
|
||||
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onHostResume(this, this);
|
||||
if (getReactNativeHost().hasInstance()) {
|
||||
getReactNativeHost().getReactInstanceManager().onHostResume(this, this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,31 +134,30 @@ public abstract class ReactActivity extends Activity
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
mReactRootView.unmountReactApplication();
|
||||
mReactRootView = null;
|
||||
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.destroy();
|
||||
if (mReactRootView != null) {
|
||||
mReactRootView.unmountReactApplication();
|
||||
mReactRootView = null;
|
||||
}
|
||||
getReactNativeHost().clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onActivityResult(requestCode, resultCode, data);
|
||||
if (getReactNativeHost().hasInstance()) {
|
||||
getReactNativeHost().getReactInstanceManager()
|
||||
.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
if (mReactInstanceManager != null &&
|
||||
mReactInstanceManager.getDevSupportManager().getDevSupportEnabled()) {
|
||||
if (getReactNativeHost().hasInstance() && getUseDeveloperSupport()) {
|
||||
if (keyCode == KeyEvent.KEYCODE_MENU) {
|
||||
mReactInstanceManager.showDevOptionsDialog();
|
||||
getReactNativeHost().getReactInstanceManager().showDevOptionsDialog();
|
||||
return true;
|
||||
}
|
||||
if (mDoubleTapReloadRecognizer.didDoubleTapR(keyCode, getCurrentFocus())) {
|
||||
mReactInstanceManager.getDevSupportManager().handleReloadJS();
|
||||
getReactNativeHost().getReactInstanceManager().getDevSupportManager().handleReloadJS();
|
||||
}
|
||||
}
|
||||
return super.onKeyUp(keyCode, event);
|
||||
@ -215,8 +165,8 @@ public abstract class ReactActivity extends Activity
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onBackPressed();
|
||||
if (getReactNativeHost().hasInstance()) {
|
||||
getReactNativeHost().getReactInstanceManager().onBackPressed();
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
@ -229,8 +179,8 @@ public abstract class ReactActivity extends Activity
|
||||
|
||||
@Override
|
||||
public void onNewIntent(Intent intent) {
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.onNewIntent(intent);
|
||||
if (getReactNativeHost().hasInstance()) {
|
||||
getReactNativeHost().getReactInstanceManager().onNewIntent(intent);
|
||||
} else {
|
||||
super.onNewIntent(intent);
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package com.facebook.react;
|
||||
|
||||
public interface ReactApplication {
|
||||
|
||||
/**
|
||||
* Get the default {@link ReactNativeHost} for this app.
|
||||
*/
|
||||
ReactNativeHost getReactNativeHost();
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package com.facebook.react;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
|
||||
/**
|
||||
* Simple class that holds an instance of {@link ReactInstanceManager}. This can be used in your
|
||||
* {@link Application class} (see {@link ReactApplication}), or as a static field.
|
||||
*/
|
||||
public abstract class ReactNativeHost {
|
||||
|
||||
private final Application mApplication;
|
||||
private @Nullable ReactInstanceManager mReactInstanceManager;
|
||||
|
||||
protected ReactNativeHost(Application application) {
|
||||
mApplication = application;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current {@link ReactInstanceManager} instance, or create one.
|
||||
*/
|
||||
public ReactInstanceManager getReactInstanceManager() {
|
||||
if (mReactInstanceManager == null) {
|
||||
mReactInstanceManager = createReactInstanceManager();
|
||||
}
|
||||
return mReactInstanceManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether this holder contains a {@link ReactInstanceManager} instance, or not. I.e. if
|
||||
* {@link #getReactInstanceManager()} has been called at least once since this object was created
|
||||
* or {@link #clear()} was called.
|
||||
*/
|
||||
public boolean hasInstance() {
|
||||
return mReactInstanceManager != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the current instance and release the internal reference to it, allowing it to be GCed.
|
||||
*/
|
||||
public void clear() {
|
||||
if (mReactInstanceManager != null) {
|
||||
mReactInstanceManager.destroy();
|
||||
mReactInstanceManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected ReactInstanceManager createReactInstanceManager() {
|
||||
ReactInstanceManager.Builder builder = ReactInstanceManager.builder()
|
||||
.setApplication(mApplication)
|
||||
.setJSMainModuleName(getJSMainModuleName())
|
||||
.setUseDeveloperSupport(getUseDeveloperSupport())
|
||||
.setInitialLifecycleState(LifecycleState.BEFORE_CREATE);
|
||||
|
||||
for (ReactPackage reactPackage : getPackages()) {
|
||||
builder.addPackage(reactPackage);
|
||||
}
|
||||
|
||||
String jsBundleFile = getJSBundleFile();
|
||||
if (jsBundleFile != null) {
|
||||
builder.setJSBundleFile(jsBundleFile);
|
||||
} else {
|
||||
builder.setBundleAssetName(Assertions.assertNotNull(getBundleAssetName()));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the main module. Determines the URL used to fetch the JS bundle
|
||||
* from the packager server. It is only used when dev support is enabled.
|
||||
* This is the first file to be executed once the {@link ReactInstanceManager} is created.
|
||||
* e.g. "index.android"
|
||||
*/
|
||||
protected String getJSMainModuleName() {
|
||||
return "index.android";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a custom path of the bundle file. This is used in cases the bundle should be loaded
|
||||
* from a custom path. By default it is loaded from Android assets, from a path specified
|
||||
* by {@link getBundleAssetName}.
|
||||
* e.g. "file://sdcard/myapp_cache/index.android.bundle"
|
||||
*/
|
||||
protected @Nullable String getJSBundleFile() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the bundle in assets. If this is null, and no file path is specified for
|
||||
* the bundle, the app will only work with {@code getUseDeveloperSupport} enabled and will
|
||||
* always try to load the JS bundle from the packager server.
|
||||
* e.g. "index.android.bundle"
|
||||
*/
|
||||
protected @Nullable String getBundleAssetName() {
|
||||
return "index.android.bundle";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether dev mode should be enabled. This enables e.g. the dev menu.
|
||||
*/
|
||||
protected abstract boolean getUseDeveloperSupport();
|
||||
|
||||
/**
|
||||
* Returns a list of {@link ReactPackage} used by the app.
|
||||
* You'll most likely want to return at least the {@code MainReactPackage}.
|
||||
* If your app uses additional views or modules besides the default ones,
|
||||
* you'll want to include more packages here.
|
||||
*/
|
||||
protected abstract List<ReactPackage> getPackages();
|
||||
}
|
@ -1,11 +1,6 @@
|
||||
package <%= package %>;
|
||||
|
||||
import com.facebook.react.ReactActivity;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.shell.MainReactPackage;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class MainActivity extends ReactActivity {
|
||||
|
||||
@ -17,24 +12,4 @@ public class MainActivity extends ReactActivity {
|
||||
protected String getMainComponentName() {
|
||||
return "<%= name %>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether dev mode should be enabled.
|
||||
* This enables e.g. the dev menu.
|
||||
*/
|
||||
@Override
|
||||
protected boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of packages used by the app. If the app uses additional views
|
||||
* or modules besides the default ones, add more packages here.
|
||||
*/
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
return Arrays.<ReactPackage>asList(
|
||||
new MainReactPackage()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
package <%= package %>;
|
||||
|
||||
import android.app.Application;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.shell.MainReactPackage;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class MainApplication extends Application implements ReactApplication {
|
||||
|
||||
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
|
||||
@Override
|
||||
protected boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
return Arrays.<ReactPackage>asList(
|
||||
new MainReactPackage()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public ReactNativeHost getReactNativeHost() {
|
||||
return mReactNativeHost;
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@
|
||||
android:targetSdkVersion="22" />
|
||||
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
android:allowBackup="true"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
|
Loading…
x
Reference in New Issue
Block a user