Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No static method builder() Lcom/facebook/react/ReactInstanceManager$Builder; #7

Open
nadirHomeFriend opened this issue Apr 24, 2018 · 0 comments

Comments

@nadirHomeFriend
Copy link

nadirHomeFriend commented Apr 24, 2018

hello,
dam facing an issue with react)native)gem when app is killer . every thing works fine when app foreground/bacground but when app is killer the app crash when receiving the notification:

04-24 16:14:47.858 4569-4569/? E/Zygote: v2
04-24 16:14:47.868 4569-4569/? E/Zygote: accessInfo : 0
04-24 16:14:48.588 4569-4569/com.homefriend.app.staging E/UncaughtException: java.lang.NoSuchMethodError: No static method builder()Lcom/facebook/react/ReactInstanceManager$Builder; in class Lcom/facebook/react/ReactInstanceManager; or its super classes (declaration of 'com.facebook.react.ReactInstanceManager' appears in /data/app/com.homefriend.app.staging-1/base.apk)
at com.oney.gcm.BackgroundService.onStartCommand(BackgroundService.java:28)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4062)
at android.app.ActivityThread.access$2400(ActivityThread.java:221)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1897)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7225)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
04-24 16:14:48.868 4569-4569/com.homefriend.app.staging E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.homefriend.app.staging, PID: 4569
java.lang.NoSuchMethodError: No static method builder()Lcom/facebook/react/ReactInstanceManager$Builder; in class Lcom/facebook/react/ReactInstanceManager; or its super classes (declaration of 'com.facebook.react.ReactInstanceManager' appears in /data/app/com.homefriend.app.staging-1/base.apk)
at com.oney.gcm.BackgroundService.onStartCommand(BackgroundService.java:28)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4062)
at android.app.ActivityThread.access$2400(ActivityThread.java:221)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1897)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7225)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

"react-native": "0.44.0",
"react": "16.0.0-alpha.6",
"react-native-gcm-android": "^0.2.0",
"react-native-system-notification": "^0.2.1",

backgroundService.java:

package com.oney.gcm;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import com.facebook.react.LifecycleState;
import com.facebook.react.ReactInstanceManager;

import java.lang.reflect.Field;

import io.neson.react.notification.NotificationPackage;

public class BackgroundService extends Service {
private static final String TAG = "BackgroundService";
private static ReactInstanceManager mReactInstanceManager;

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d(TAG, "onStartCommand");

    mReactInstanceManager = ReactInstanceManager.builder()
            .setApplication(getApplication())
            .setBundleAssetName("index.android.bundle")
            .setJSMainModuleName("index.android")
            .addPackage(new MainReactPackage())
            .addPackage(new GcmPackage(intent))
            .addPackage(new NotificationPackage())
            .setUseDeveloperSupport(getBuildConfigDEBUG())
            .setInitialLifecycleState(LifecycleState.RESUMED)
            .build();
    mReactInstanceManager.createReactContextInBackground();

    return START_NOT_STICKY;
}
 //   @Override

/* public int onStartCommand(Intent intent, int flags, int startId) {

Bundle bundle = intent.getBundleExtra("bundle");
Object result = bundle.get("info");
String data   = result.toString();
String id     = bundle.get("google.message_id").toString();
try{
    JSONObject jsonObj = new JSONObject(data);
    Log.d(TAG,"onStartCommand jsonObj => :"+jsonObj);
    Log.d(TAG,"onStartCommand bundle => :"+bundle);
    String message = jsonObj.getString("message");
    String subject = jsonObj.getString("subject");
    Integer notificationId = Integer.parseInt(id.substring(0, 10).replaceAll("[\\D]", ""));

    NotificationAttributes attributes = new NotificationAttributes();
    attributes.delayed = false;
    attributes.scheduled = false;
    attributes.autoClear = true;
    attributes.inboxStyle = false;
    attributes.priority = 2;
    attributes.sound = "default";
    attributes.smallIcon = "ic_launcher";
    attributes.message = message;
    attributes.subject = subject;
    Notification notification = new Notification(this, notificationId, attributes);
    notification.create();

}catch (JSONException e) {
   Log.d(TAG,e);
}  
return START_NOT_STICKY;

}*/
@OverRide
public void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
mReactInstanceManager.onPause();
mReactInstanceManager.onDestroy();
mReactInstanceManager = null;
}

private Class getBuildConfigClass() {
    try {
        String packageName = getPackageName();

        return Class.forName(packageName + ".BuildConfig");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
        return null;
    }
}
private boolean getBuildConfigDEBUG() {
    Class klass = getBuildConfigClass();
    for (Field f : klass.getDeclaredFields()) {
        if (f.getName().equals("DEBUG")) {
            try {
                return f.getBoolean(this);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
    return false;
}

}

ReactInstanceManager.java:

/**

  • 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.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Process;
import android.view.View;

import com.facebook.common.logging.FLog;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.CatalystInstance;
import com.facebook.react.bridge.JavaJSExecutor;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.JavaScriptModuleRegistry;
import com.facebook.react.bridge.NativeModuleCallExceptionHandler;
import com.facebook.react.bridge.NotThreadSafeBridgeIdleDebugListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactMarker;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;
import com.facebook.react.bridge.queue.ReactQueueConfigurationSpec;
import com.facebook.react.common.ApplicationHolder;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.cxxbridge.Arguments;
import com.facebook.react.cxxbridge.CatalystInstanceImpl;
import com.facebook.react.cxxbridge.JSBundleLoader;
import com.facebook.react.cxxbridge.JSCJavaScriptExecutor;
import com.facebook.react.cxxbridge.JavaScriptExecutor;
import com.facebook.react.cxxbridge.NativeModuleRegistry;
import com.facebook.react.cxxbridge.ProxyJavaScriptExecutor;
import com.facebook.react.cxxbridge.UiThreadUtil;
import com.facebook.react.devsupport.DevSupportManagerFactory;
import com.facebook.react.devsupport.ReactInstanceDevCommandsHandler;
import com.facebook.react.devsupport.RedBoxHandler;
import com.facebook.react.devsupport.interfaces.DevSupportManager;
import com.facebook.react.devsupport.interfaces.PackagerStatusCallback;
import com.facebook.react.modules.appregistry.AppRegistry;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.modules.debug.interfaces.DeveloperSettings;
import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.UIImplementationProvider;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
import com.facebook.soloader.SoLoader;
import com.facebook.systrace.Systrace;
import com.facebook.systrace.SystraceMessage;

import static com.facebook.react.bridge.ReactMarkerConstants.BUILD_NATIVE_MODULE_REGISTRY_END;
import static com.facebook.react.bridge.ReactMarkerConstants.BUILD_NATIVE_MODULE_REGISTRY_START;
import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_CATALYST_INSTANCE_END;
import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_CATALYST_INSTANCE_START;
import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_REACT_CONTEXT_START;
import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_VIEW_MANAGERS_END;
import static com.facebook.react.bridge.ReactMarkerConstants.CREATE_VIEW_MANAGERS_START;
import static com.facebook.react.bridge.ReactMarkerConstants.PRE_SETUP_REACT_CONTEXT_END;
import static com.facebook.react.bridge.ReactMarkerConstants.PRE_SETUP_REACT_CONTEXT_START;
import static com.facebook.react.bridge.ReactMarkerConstants.PROCESS_PACKAGES_END;
import static com.facebook.react.bridge.ReactMarkerConstants.PROCESS_PACKAGES_START;
import static com.facebook.react.bridge.ReactMarkerConstants.SETUP_REACT_CONTEXT_END;
import static com.facebook.react.bridge.ReactMarkerConstants.SETUP_REACT_CONTEXT_START;
import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_APPS;
import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE;
import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JSC_CALLS;

/**

  • This class is managing instances of {@link CatalystInstance}. It exposes a way to configure
  • catalyst instance using {@link ReactPackage} and keeps track of the lifecycle of that
  • instance. It also sets up connection between the instance and developers support functionality
  • of the framework.
  • An instance of this manager is required to start JS application in {@link ReactRootView} (see
  • {@link ReactRootView#startReactApplication} for more info).
  • The lifecycle of the instance of {@link ReactInstanceManager} should be bound to the
  • activity that owns the {@link ReactRootView} that is used to render react application using this
  • instance manager (see {@link ReactRootView#startReactApplication}). It's required to pass owning
  • activity's lifecycle events to the instance manager (see {@link #onHostPause}, {@link
  • #onHostDestroy} and {@link #onHostResume}).
  • To instantiate an instance of this class use {@link #builder}.
    */
    public class ReactInstanceManager {

private static final String TAG = ReactInstanceManager.class.getSimpleName();

/**

  • Listener interface for react instance events.
    /
    public interface ReactInstanceEventListener {
    /
    *
    • Called when the react context is initialized (all modules registered). Always called on the
    • UI thread.
      */
      void onReactContextInitialized(ReactContext context);
      }

/* should only be accessed from main thread (UI thread) */
private final List mAttachedRootViews = new ArrayList<>();
private LifecycleState mLifecycleState;
private @nullable ReactContextInitParams mPendingReactContextInitParams;
private @nullable ReactContextInitAsyncTask mReactContextInitAsyncTask;
private @nullable Thread mCreateReactContextThread;

/* accessed from any thread /
private final @nullable JSBundleLoader mBundleLoader; /
path to JS bundle on file system /
private final @nullable String mJSMainModuleName; /
path to JS bundle root on packager server */
private final List mPackages;
private final DevSupportManager mDevSupportManager;
private final boolean mUseDeveloperSupport;
private final @nullable NotThreadSafeBridgeIdleDebugListener mBridgeIdleDebugListener;
private @nullable volatile ReactContext mCurrentReactContext;
private final Context mApplicationContext;
private @nullable DefaultHardwareBackBtnHandler mDefaultBackButtonImpl;
private @nullable Activity mCurrentActivity;
private final Collection mReactInstanceEventListeners =
Collections.synchronizedSet(new HashSet());
private volatile boolean mHasStartedCreatingInitialContext = false;
private final UIImplementationProvider mUIImplementationProvider;
private final MemoryPressureRouter mMemoryPressureRouter;
private final @nullable NativeModuleCallExceptionHandler mNativeModuleCallExceptionHandler;
private final JSCConfig mJSCConfig;
private final boolean mLazyNativeModulesEnabled;
private final boolean mLazyViewManagersEnabled;
private final boolean mUseStartupThread;

private final ReactInstanceDevCommandsHandler mDevInterface =
new ReactInstanceDevCommandsHandler() {

    @Override
    public void onReloadWithJSDebugger(JavaJSExecutor.Factory jsExecutorFactory) {
      ReactInstanceManager.this.onReloadWithJSDebugger(jsExecutorFactory);
    }

    @Override
    public void onJSBundleLoadedFromServer() {
      ReactInstanceManager.this.onJSBundleLoadedFromServer();
    }

    @Override
    public void toggleElementInspector() {
      ReactInstanceManager.this.toggleElementInspector();
    }
  };

private final DefaultHardwareBackBtnHandler mBackBtnHandler =
new DefaultHardwareBackBtnHandler() {
@OverRide
public void invokeDefaultOnBackPressed() {
ReactInstanceManager.this.invokeDefaultOnBackPressed();
}
};

private class ReactContextInitParams {
private final JavaScriptExecutor.Factory mJsExecutorFactory;
private final JSBundleLoader mJsBundleLoader;

public ReactContextInitParams(
    JavaScriptExecutor.Factory jsExecutorFactory,
    JSBundleLoader jsBundleLoader) {
  mJsExecutorFactory = Assertions.assertNotNull(jsExecutorFactory);
  mJsBundleLoader = Assertions.assertNotNull(jsBundleLoader);
}

public JavaScriptExecutor.Factory getJsExecutorFactory() {
  return mJsExecutorFactory;
}

public JSBundleLoader getJsBundleLoader() {
  return mJsBundleLoader;
}

}

/*

  • Task class responsible for (re)creating react context in the background. These tasks can only
  • be executing one at time, see {@link #recreateReactContextInBackground()}.
    */
    private final class ReactContextInitAsyncTask extends
    AsyncTask<ReactContextInitParams, Void, Result> {
    @OverRide
    protected void onPreExecute() {
    if (mCurrentReactContext != null) {
    tearDownReactContext(mCurrentReactContext);
    mCurrentReactContext = null;
    }
    }
@Override
protected Result<ReactApplicationContext> doInBackground(ReactContextInitParams... params) {
  // TODO(t11687218): Look over all threading
  // Default priority is Process.THREAD_PRIORITY_BACKGROUND which means we'll be put in a cgroup
  // that only has access to a small fraction of CPU time. The priority will be reset after
  // this task finishes: https://android.googlesource.com/platform/frameworks/base/+/d630f105e8bc0021541aacb4dc6498a49048ecea/core/java/android/os/AsyncTask.java#256
  Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);

  Assertions.assertCondition(params != null && params.length > 0 && params[0] != null);
  try {
    JavaScriptExecutor jsExecutor = params[0].getJsExecutorFactory().create();
    ReactApplicationContext reactApplicationContext =
      createReactContext(jsExecutor, params[0].getJsBundleLoader());
    ReactMarker.logMarker(PRE_SETUP_REACT_CONTEXT_START);
    return Result.of(reactApplicationContext);
  } catch (Exception e) {
    // Pass exception to onPostExecute() so it can be handled on the main thread
    return Result.of(e);
  }
}

@Override
protected void onPostExecute(Result<ReactApplicationContext> result) {
  try {
    setupReactContext(result.get());
  } catch (Exception e) {
    mDevSupportManager.handleException(e);
  } finally {
    mReactContextInitAsyncTask = null;
  }

  // Handle enqueued request to re-initialize react context.
  if (mPendingReactContextInitParams != null) {
    recreateReactContextInBackground(
      mPendingReactContextInitParams.getJsExecutorFactory(),
      mPendingReactContextInitParams.getJsBundleLoader());
    mPendingReactContextInitParams = null;
  }
}

@Override
protected void onCancelled(Result<ReactApplicationContext> reactApplicationContextResult) {
  try {
    mMemoryPressureRouter.destroy(reactApplicationContextResult.get());
  } catch (Exception e) {
    FLog.w(ReactConstants.TAG, "Caught exception after cancelling react context init", e);
  } finally {
    mReactContextInitAsyncTask = null;
  }
}

}

private static class Result {
@nullable private final T mResult;
@nullable private final Exception mException;

public static <T, U extends T> Result<T> of(U result) {
  return new Result<T>(result);
}

public static <T> Result<T> of(Exception exception) {
  return new Result<>(exception);
}

private Result(T result) {
  mException = null;
  mResult = result;
}

private Result(Exception exception) {
  mException = exception;
  mResult = null;
}

public T get() throws Exception {
  if (mException != null) {
    throw mException;
  }

  Assertions.assertNotNull(mResult);

  return mResult;
}

}

/**

  • Creates a builder that is capable of creating an instance of {@link ReactInstanceManager}.
    */
    public static ReactInstanceManagerBuilder builder() {
    return new ReactInstanceManagerBuilder();
    }

/* package */ ReactInstanceManager(
Context applicationContext,
@nullable Activity currentActivity,
@nullable DefaultHardwareBackBtnHandler defaultHardwareBackBtnHandler,
@nullable JSBundleLoader bundleLoader,
@nullable String jsMainModuleName,
List packages,
boolean useDeveloperSupport,
@nullable NotThreadSafeBridgeIdleDebugListener bridgeIdleDebugListener,
LifecycleState initialLifecycleState,
UIImplementationProvider uiImplementationProvider,
NativeModuleCallExceptionHandler nativeModuleCallExceptionHandler,
JSCConfig jscConfig,
@nullable RedBoxHandler redBoxHandler,
boolean lazyNativeModulesEnabled,
boolean lazyViewManagersEnabled,
boolean useStartupThread) {

initializeSoLoaderIfNecessary(applicationContext);

// TODO(9577825): remove this
ApplicationHolder.setApplication((Application) applicationContext.getApplicationContext());
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(applicationContext);

mApplicationContext = applicationContext;
mCurrentActivity = currentActivity;
mDefaultBackButtonImpl = defaultHardwareBackBtnHandler;
mBundleLoader = bundleLoader;
mJSMainModuleName = jsMainModuleName;
mPackages = packages;
mUseDeveloperSupport = useDeveloperSupport;
mDevSupportManager = DevSupportManagerFactory.create(
    applicationContext,
    mDevInterface,
    mJSMainModuleName,
    useDeveloperSupport,
    redBoxHandler);
mBridgeIdleDebugListener = bridgeIdleDebugListener;
mLifecycleState = initialLifecycleState;
mUIImplementationProvider = uiImplementationProvider;
mMemoryPressureRouter = new MemoryPressureRouter(applicationContext);
mNativeModuleCallExceptionHandler = nativeModuleCallExceptionHandler;
mJSCConfig = jscConfig;
mLazyNativeModulesEnabled = lazyNativeModulesEnabled;
mLazyViewManagersEnabled = lazyViewManagersEnabled;
mUseStartupThread = useStartupThread;

}

public DevSupportManager getDevSupportManager() {
return mDevSupportManager;
}

public MemoryPressureRouter getMemoryPressureRouter() {
return mMemoryPressureRouter;
}

private static void initializeSoLoaderIfNecessary(Context applicationContext) {
// Call SoLoader.initialize here, this is required for apps that does not use exopackage and
// does not use SoLoader for loading other native code except from the one used by React Native
// This way we don't need to require others to have additional initialization code and to
// subclass android.app.Application.

// Method SoLoader.init is idempotent, so if you wish to use native exopackage, just call
// SoLoader.init with appropriate args before initializing ReactInstanceManager
SoLoader.init(applicationContext, /* native exopackage */ false);

}

/**

  • Trigger react context initialization asynchronously in a background async task. This enables
  • applications to pre-load the application JS, and execute global code before
  • {@link ReactRootView} is available and measured. This should only be called the first time the
  • application is set up, which is enforced to keep developers from accidentally creating their
  • application multiple times without realizing it.
  • Called from UI thread.
    */
    public void createReactContextInBackground() {
    Assertions.assertCondition(
    !mHasStartedCreatingInitialContext,
    "createReactContextInBackground should only be called when creating the react " +
    "application for the first time. When reloading JS, e.g. from a new file, explicitly" +
    "use recreateReactContextInBackground");
mHasStartedCreatingInitialContext = true;
recreateReactContextInBackgroundInner();

}

/**

  • Recreate the react application and context. This should be called if configuration has
  • changed or the developer has requested the app to be reloaded. It should only be called after
  • an initial call to createReactContextInBackground.
  • Called from UI thread.
    */
    public void recreateReactContextInBackground() {
    Assertions.assertCondition(
    mHasStartedCreatingInitialContext,
    "recreateReactContextInBackground should only be called after the initial " +
    "createReactContextInBackground call.");
    recreateReactContextInBackgroundInner();
    }

private void recreateReactContextInBackgroundInner() {
UiThreadUtil.assertOnUiThread();

if (mUseDeveloperSupport && mJSMainModuleName != null) {
  final DeveloperSettings devSettings = mDevSupportManager.getDevSettings();

  // If remote JS debugging is enabled, load from dev server.
  if (mDevSupportManager.hasUpToDateJSBundleInCache() &&
      !devSettings.isRemoteJSDebugEnabled()) {
    // If there is a up-to-date bundle downloaded from server,
    // with remote JS debugging disabled, always use that.
    onJSBundleLoadedFromServer();
  } else if (mBundleLoader == null) {
    mDevSupportManager.handleReloadJS();
  } else {
    mDevSupportManager.isPackagerRunning(
        new PackagerStatusCallback() {
          @Override
          public void onPackagerStatusFetched(final boolean packagerIsRunning) {
            UiThreadUtil.runOnUiThread(
                new Runnable() {
                  @Override
                  public void run() {
                    if (packagerIsRunning) {
                      mDevSupportManager.handleReloadJS();
                    } else {
                      // If dev server is down, disable the remote JS debugging.
                      devSettings.setRemoteJSDebugEnabled(false);
                      recreateReactContextInBackgroundFromBundleLoader();
                    }
                  }
                });
          }
        });
  }
  return;
}

recreateReactContextInBackgroundFromBundleLoader();

}

private void recreateReactContextInBackgroundFromBundleLoader() {
recreateReactContextInBackground(
new JSCJavaScriptExecutor.Factory(mJSCConfig.getConfigMap()),
mBundleLoader);
}

/**

  • @return whether createReactContextInBackground has been called. Will return false after
  • onDestroy until a new initial context has been created.
    */
    public boolean hasStartedCreatingInitialContext() {
    return mHasStartedCreatingInitialContext;
    }

/**

  • This method will give JS the opportunity to consume the back button event. If JS does not
  • consume the event, mDefaultBackButtonImpl will be invoked at the end of the round trip to JS.
    */
    public void onBackPressed() {
    UiThreadUtil.assertOnUiThread();
    ReactContext reactContext = mCurrentReactContext;
    if (mCurrentReactContext == null) {
    // Invoke without round trip to JS.
    FLog.w(ReactConstants.TAG, "Instance detached from instance manager");
    invokeDefaultOnBackPressed();
    } else {
    DeviceEventManagerModule deviceEventManagerModule =
    Assertions.assertNotNull(reactContext).getNativeModule(DeviceEventManagerModule.class);
    deviceEventManagerModule.emitHardwareBackPressed();
    }
    }

private void invokeDefaultOnBackPressed() {
UiThreadUtil.assertOnUiThread();
if (mDefaultBackButtonImpl != null) {
mDefaultBackButtonImpl.invokeDefaultOnBackPressed();
}
}

/**

  • This method will give JS the opportunity to receive intents via Linking.
    */
    public void onNewIntent(Intent intent) {
    if (mCurrentReactContext == null) {
    FLog.w(ReactConstants.TAG, "Instance detached from instance manager");
    } else {
    String action = intent.getAction();
    Uri uri = intent.getData();

    if (Intent.ACTION_VIEW.equals(action) && uri != null) {
    DeviceEventManagerModule deviceEventManagerModule =
    Assertions.assertNotNull(mCurrentReactContext).getNativeModule(DeviceEventManagerModule.class);
    deviceEventManagerModule.emitNewIntentReceived(uri);
    }

    mCurrentReactContext.onNewIntent(mCurrentActivity, intent);
    }
    }

private void toggleElementInspector() {
if (mCurrentReactContext != null) {
mCurrentReactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("toggleElementInspector", null);
}
}

/**

  • Call this from {@link Activity#onPause()}. This notifies any listening modules so they can do
  • any necessary cleanup.
  • @deprecated Use {@link #onHostPause(Activity)} instead.
    */
    public void onHostPause() {
    UiThreadUtil.assertOnUiThread();
mDefaultBackButtonImpl = null;
if (mUseDeveloperSupport) {
  mDevSupportManager.setDevSupportEnabled(false);
}

moveToBeforeResumeLifecycleState();

}

/**

  • Call this from {@link Activity#onPause()}. This notifies any listening modules so they can do
  • any necessary cleanup. The passed Activity is the current Activity being paused. This will
  • always be the foreground activity that would be returned by
  • {@link ReactContext#getCurrentActivity()}.
  • @param activity the activity being paused
    */
    public void onHostPause(Activity activity) {
    Assertions.assertNotNull(mCurrentActivity);
    Assertions.assertCondition(
    activity == mCurrentActivity,
    "Pausing an activity that is not the current activity, this is incorrect! " +
    "Current activity: " + mCurrentActivity.getClass().getSimpleName() + " " +
    "Paused activity: " + activity.getClass().getSimpleName());
    onHostPause();
    }

/**

  • Use this method when the activity resumes to enable invoking the back button directly from JS.
  • This method retains an instance to provided mDefaultBackButtonImpl. Thus it's important to pass
  • from the activity instance that owns this particular instance of {@link
  • ReactInstanceManager}, so that once this instance receive {@link #onHostDestroy} event it
  • will clear the reference to that defaultBackButtonImpl.
  • @param defaultBackButtonImpl a {@link DefaultHardwareBackBtnHandler} from an Activity that owns
  • this instance of {@link ReactInstanceManager}.
    */
    public void onHostResume(Activity activity, DefaultHardwareBackBtnHandler defaultBackButtonImpl) {
    UiThreadUtil.assertOnUiThread();
mDefaultBackButtonImpl = defaultBackButtonImpl;
if (mUseDeveloperSupport) {
  mDevSupportManager.setDevSupportEnabled(true);
}

mCurrentActivity = activity;
moveToResumedLifecycleState(false);

}

/**

  • Call this from {@link Activity#onDestroy()}. This notifies any listening modules so they can do
  • any necessary cleanup.
  • @deprecated use {@link #onHostDestroy(Activity)} instead
    */
    public void onHostDestroy() {
    UiThreadUtil.assertOnUiThread();
if (mUseDeveloperSupport) {
  mDevSupportManager.setDevSupportEnabled(false);
}

moveToBeforeCreateLifecycleState();
mCurrentActivity = null;

}

/**

  • Call this from {@link Activity#onDestroy()}. This notifies any listening modules so they can do
  • any necessary cleanup. If the activity being destroyed is not the current activity, no modules
  • are notified.
  • @param activity the activity being destroyed
    */
    public void onHostDestroy(Activity activity) {
    if (activity == mCurrentActivity) {
    onHostDestroy();
    }
    }

/**

  • Destroy this React instance and the attached JS context.
    */
    public void destroy() {
    UiThreadUtil.assertOnUiThread();
if (mUseDeveloperSupport) {
  mDevSupportManager.setDevSupportEnabled(false);
}

moveToBeforeCreateLifecycleState();

if (mReactContextInitAsyncTask != null) {
  mReactContextInitAsyncTask.cancel(true);
}

if (mCreateReactContextThread != null) {
  mCreateReactContextThread.interrupt();
  mCreateReactContextThread = null;
}

mMemoryPressureRouter.destroy(mApplicationContext);

if (mCurrentReactContext != null) {
  mCurrentReactContext.destroy();
  mCurrentReactContext = null;
  mHasStartedCreatingInitialContext = false;
}
mCurrentActivity = null;

ResourceDrawableIdHelper.getInstance().clear();

}

private void moveToResumedLifecycleState(boolean force) {
if (mCurrentReactContext != null) {
// we currently don't have an onCreate callback so we call onResume for both transitions
if (force ||
mLifecycleState == LifecycleState.BEFORE_RESUME ||
mLifecycleState == LifecycleState.BEFORE_CREATE) {
mCurrentReactContext.onHostResume(mCurrentActivity);
}
}
mLifecycleState = LifecycleState.RESUMED;
}

private void moveToBeforeResumeLifecycleState() {
if (mCurrentReactContext != null) {
if (mLifecycleState == LifecycleState.BEFORE_CREATE) {
mCurrentReactContext.onHostResume(mCurrentActivity);
mCurrentReactContext.onHostPause();
} else if (mLifecycleState == LifecycleState.RESUMED) {
mCurrentReactContext.onHostPause();
}
}
mLifecycleState = LifecycleState.BEFORE_RESUME;
}

private void moveToBeforeCreateLifecycleState() {
if (mCurrentReactContext != null) {
if (mLifecycleState == LifecycleState.RESUMED) {
mCurrentReactContext.onHostPause();
mLifecycleState = LifecycleState.BEFORE_RESUME;
}
if (mLifecycleState == LifecycleState.BEFORE_RESUME) {
mCurrentReactContext.onHostDestroy();
}
}
mLifecycleState = LifecycleState.BEFORE_CREATE;
}

public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
if (mCurrentReactContext != null) {
mCurrentReactContext.onActivityResult(activity, requestCode, resultCode, data);
}
}

public void showDevOptionsDialog() {
UiThreadUtil.assertOnUiThread();
mDevSupportManager.showDevOptionsDialog();
}

/**

  • Attach given {@param rootView} to a catalyst instance manager and start JS application using
  • JS module provided by {@link ReactRootView#getJSModuleName}. If the react context is currently
  • being (re)-created, or if react context has not been created yet, the JS application associated
  • with the provided root view will be started asynchronously, i.e this method won't block.
  • This view will then be tracked by this manager and in case of catalyst instance restart it will
  • be re-attached.
    */
    public void attachMeasuredRootView(ReactRootView rootView) {
    UiThreadUtil.assertOnUiThread();
    mAttachedRootViews.add(rootView);
// If react context is being created in the background, JS application will be started
// automatically when creation completes, as root view is part of the attached root view list.
if (mReactContextInitAsyncTask == null &&
  mCreateReactContextThread == null &&
  mCurrentReactContext != null) {
  attachMeasuredRootViewToInstance(rootView, mCurrentReactContext.getCatalystInstance());
}

}

/**

  • Detach given {@param rootView} from current catalyst instance. It's safe to call this method
  • multiple times on the same {@param rootView} - in that case view will be detached with the
  • first call.
    */
    public void detachRootView(ReactRootView rootView) {
    UiThreadUtil.assertOnUiThread();
    if (mAttachedRootViews.remove(rootView)) {
    if (mCurrentReactContext != null && mCurrentReactContext.hasActiveCatalystInstance()) {
    detachViewFromInstance(rootView, mCurrentReactContext.getCatalystInstance());
    }
    }
    }

/**

  • Uses configured {@link ReactPackage} instances to create all view managers.
    */
    public List createAllViewManagers(
    ReactApplicationContext catalystApplicationContext) {
    ReactMarker.logMarker(CREATE_VIEW_MANAGERS_START);
    Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "createAllViewManagers");
    try {
    List allViewManagers = new ArrayList<>();
    for (ReactPackage reactPackage : mPackages) {
    allViewManagers.addAll(reactPackage.createViewManagers(catalystApplicationContext));
    }
    return allViewManagers;
    } finally {
    Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
    ReactMarker.logMarker(CREATE_VIEW_MANAGERS_END);
    }
    }

/**

  • Add a listener to be notified of react instance events.
    */
    public void addReactInstanceEventListener(ReactInstanceEventListener listener) {
    mReactInstanceEventListeners.add(listener);
    }

/**

  • Remove a listener previously added with {@link #addReactInstanceEventListener}.
    */
    public void removeReactInstanceEventListener(ReactInstanceEventListener listener) {
    mReactInstanceEventListeners.remove(listener);
    }

@VisibleForTesting
public @nullable ReactContext getCurrentReactContext() {
return mCurrentReactContext;
}

public LifecycleState getLifecycleState() {
return mLifecycleState;
}

private void onReloadWithJSDebugger(JavaJSExecutor.Factory jsExecutorFactory) {
recreateReactContextInBackground(
new ProxyJavaScriptExecutor.Factory(jsExecutorFactory),
JSBundleLoader.createRemoteDebuggerBundleLoader(
mDevSupportManager.getJSBundleURLForRemoteDebugging(),
mDevSupportManager.getSourceUrl()));
}

private void onJSBundleLoadedFromServer() {
recreateReactContextInBackground(
new JSCJavaScriptExecutor.Factory(mJSCConfig.getConfigMap()),
JSBundleLoader.createCachedBundleFromNetworkLoader(
mDevSupportManager.getSourceUrl(),
mDevSupportManager.getDownloadedJSBundleFile()));
}

private void recreateReactContextInBackground(
JavaScriptExecutor.Factory jsExecutorFactory,
JSBundleLoader jsBundleLoader) {
UiThreadUtil.assertOnUiThread();

final ReactContextInitParams initParams = new ReactContextInitParams(
  jsExecutorFactory,
  jsBundleLoader);
if (mUseStartupThread) {
  if (mCreateReactContextThread == null) {
    runCreateReactContextOnNewThread(initParams);
  } else {
    mPendingReactContextInitParams = initParams;
  }
} else {
  if (mReactContextInitAsyncTask == null) {
    // No background task to create react context is currently running, create and execute one.
    mReactContextInitAsyncTask = new ReactContextInitAsyncTask();
    mReactContextInitAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, initParams);
  } else {
    // Background task is currently running, queue up most recent init params to recreate context
    // once task completes.
    mPendingReactContextInitParams = initParams;
  }
}

}

private void runCreateReactContextOnNewThread(final ReactContextInitParams initParams) {
if (mCurrentReactContext != null) {
tearDownReactContext(mCurrentReactContext);
mCurrentReactContext = null;
}

mCreateReactContextThread = new Thread(new Runnable() {
  @Override
  public void run() {
    try {
      final ReactApplicationContext reactApplicationContext = createReactContext(
        initParams.getJsExecutorFactory().create(),
        initParams.getJsBundleLoader());
      ReactMarker.logMarker(PRE_SETUP_REACT_CONTEXT_START);
      UiThreadUtil.runOnUiThread(new Runnable() {
        @Override
        public void run() {
          mCreateReactContextThread = null;
          try {
            setupReactContext(reactApplicationContext);
          } catch (Exception e) {
            mDevSupportManager.handleException(e);
          }

          if (mPendingReactContextInitParams != null) {
            runCreateReactContextOnNewThread(mPendingReactContextInitParams);
            mPendingReactContextInitParams = null;
          }
        }
      });
    } catch (Exception e) {
      mDevSupportManager.handleException(e);
    }
  }
});
mCreateReactContextThread.setPriority(Thread.MAX_PRIORITY);
mCreateReactContextThread.start();

}

private void setupReactContext(ReactApplicationContext reactContext) {
ReactMarker.logMarker(PRE_SETUP_REACT_CONTEXT_END);
ReactMarker.logMarker(SETUP_REACT_CONTEXT_START);
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "setupReactContext");
UiThreadUtil.assertOnUiThread();
Assertions.assertCondition(mCurrentReactContext == null);
mCurrentReactContext = Assertions.assertNotNull(reactContext);
CatalystInstance catalystInstance =
Assertions.assertNotNull(reactContext.getCatalystInstance());

catalystInstance.initialize();
mDevSupportManager.onNewReactContextCreated(reactContext);
mMemoryPressureRouter.addMemoryPressureListener(catalystInstance);
moveReactContextToCurrentLifecycleState();

for (ReactRootView rootView : mAttachedRootViews) {
  attachMeasuredRootViewToInstance(rootView, catalystInstance);
}

ReactInstanceEventListener[] listeners =
  new ReactInstanceEventListener[mReactInstanceEventListeners.size()];
listeners = mReactInstanceEventListeners.toArray(listeners);

for (ReactInstanceEventListener listener : listeners) {
  listener.onReactContextInitialized(reactContext);
}
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
ReactMarker.logMarker(SETUP_REACT_CONTEXT_END);

}

private void attachMeasuredRootViewToInstance(
ReactRootView rootView,
CatalystInstance catalystInstance) {
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "attachMeasuredRootViewToInstance");
UiThreadUtil.assertOnUiThread();

// Reset view content as it's going to be populated by the application content from JS
rootView.removeAllViews();
rootView.setId(View.NO_ID);

UIManagerModule uiManagerModule = catalystInstance.getNativeModule(UIManagerModule.class);
int rootTag = uiManagerModule.addMeasuredRootView(rootView);
rootView.setRootViewTag(rootTag);
@Nullable Bundle launchOptions = rootView.getLaunchOptions();
WritableMap initialProps = Arguments.makeNativeMap(launchOptions);
String jsAppModuleName = rootView.getJSModuleName();

WritableNativeMap appParams = new WritableNativeMap();
appParams.putDouble("rootTag", rootTag);
appParams.putMap("initialProps", initialProps);
catalystInstance.getJSModule(AppRegistry.class).runApplication(jsAppModuleName, appParams);
rootView.onAttachedToReactInstance();
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);

}

private void detachViewFromInstance(
ReactRootView rootView,
CatalystInstance catalystInstance) {
UiThreadUtil.assertOnUiThread();
catalystInstance.getJSModule(AppRegistry.class)
.unmountApplicationComponentAtRootTag(rootView.getId());
}

private void tearDownReactContext(ReactContext reactContext) {
UiThreadUtil.assertOnUiThread();
if (mLifecycleState == LifecycleState.RESUMED) {
reactContext.onHostPause();
}
for (ReactRootView rootView : mAttachedRootViews) {
detachViewFromInstance(rootView, reactContext.getCatalystInstance());
}
reactContext.destroy();
mDevSupportManager.onReactInstanceDestroyed(reactContext);
mMemoryPressureRouter.removeMemoryPressureListener(reactContext.getCatalystInstance());
}

/**

  • @return instance of {@link ReactContext} configured a {@link CatalystInstance} set
    */
    private ReactApplicationContext createReactContext(
    JavaScriptExecutor jsExecutor,
    JSBundleLoader jsBundleLoader) {
    FLog.i(ReactConstants.TAG, "Creating react context.");
    ReactMarker.logMarker(CREATE_REACT_CONTEXT_START);
    final ReactApplicationContext reactContext = new ReactApplicationContext(mApplicationContext);
    NativeModuleRegistryBuilder nativeModuleRegistryBuilder = new NativeModuleRegistryBuilder(
    reactContext,
    this,
    mLazyNativeModulesEnabled);
    JavaScriptModuleRegistry.Builder jsModulesBuilder = new JavaScriptModuleRegistry.Builder();
    if (mUseDeveloperSupport) {
    reactContext.setNativeModuleCallExceptionHandler(mDevSupportManager);
    }
ReactMarker.logMarker(PROCESS_PACKAGES_START);
Systrace.beginSection(
    TRACE_TAG_REACT_JAVA_BRIDGE,
    "createAndProcessCoreModulesPackage");
try {
  CoreModulesPackage coreModulesPackage =
    new CoreModulesPackage(
      this,
      mBackBtnHandler,
      mUIImplementationProvider,
      mLazyViewManagersEnabled);
  processPackage(coreModulesPackage, nativeModuleRegistryBuilder, jsModulesBuilder);
} finally {
  Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
}

// TODO(6818138): Solve use-case of native/js modules overriding
for (ReactPackage reactPackage : mPackages) {
  Systrace.beginSection(
      TRACE_TAG_REACT_JAVA_BRIDGE,
      "createAndProcessCustomReactPackage");
  try {
    processPackage(reactPackage, nativeModuleRegistryBuilder, jsModulesBuilder);
  } finally {
    Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
  }
}
ReactMarker.logMarker(PROCESS_PACKAGES_END);

ReactMarker.logMarker(BUILD_NATIVE_MODULE_REGISTRY_START);
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "buildNativeModuleRegistry");
NativeModuleRegistry nativeModuleRegistry;
try {
   nativeModuleRegistry = nativeModuleRegistryBuilder.build();
} finally {
  Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
  ReactMarker.logMarker(BUILD_NATIVE_MODULE_REGISTRY_END);
}

NativeModuleCallExceptionHandler exceptionHandler = mNativeModuleCallExceptionHandler != null
    ? mNativeModuleCallExceptionHandler
    : mDevSupportManager;
CatalystInstanceImpl.Builder catalystInstanceBuilder = new CatalystInstanceImpl.Builder()
    .setReactQueueConfigurationSpec(ReactQueueConfigurationSpec.createDefault())
    .setJSExecutor(jsExecutor)
    .setRegistry(nativeModuleRegistry)
    .setJSModuleRegistry(jsModulesBuilder.build())
    .setJSBundleLoader(jsBundleLoader)
    .setNativeModuleCallExceptionHandler(exceptionHandler);

ReactMarker.logMarker(CREATE_CATALYST_INSTANCE_START);
// CREATE_CATALYST_INSTANCE_END is in JSCExecutor.cpp
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "createCatalystInstance");
final CatalystInstance catalystInstance;
try {
  catalystInstance = catalystInstanceBuilder.build();
} finally {
  Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
  ReactMarker.logMarker(CREATE_CATALYST_INSTANCE_END);
}

if (mBridgeIdleDebugListener != null) {
  catalystInstance.addBridgeIdleDebugListener(mBridgeIdleDebugListener);
}
if (Systrace.isTracing(TRACE_TAG_REACT_APPS | TRACE_TAG_REACT_JSC_CALLS)) {
  catalystInstance.setGlobalVariable("__RCTProfileIsProfiling", "true");
}

reactContext.initializeWithInstance(catalystInstance);
catalystInstance.runJSBundle();

return reactContext;

}

private void processPackage(
ReactPackage reactPackage,
NativeModuleRegistryBuilder nativeModuleRegistryBuilder,
JavaScriptModuleRegistry.Builder jsModulesBuilder) {
SystraceMessage.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "processPackage")
.arg("className", reactPackage.getClass().getSimpleName())
.flush();
if (reactPackage instanceof ReactPackageLogger) {
((ReactPackageLogger) reactPackage).startProcessPackage();
}
nativeModuleRegistryBuilder.processPackage(reactPackage);

for (Class<? extends JavaScriptModule> jsModuleClass : reactPackage.createJSModules()) {
  jsModulesBuilder.add(jsModuleClass);
}
if (reactPackage instanceof ReactPackageLogger) {
  ((ReactPackageLogger) reactPackage).endProcessPackage();
}
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);

}

private void moveReactContextToCurrentLifecycleState() {
if (mLifecycleState == LifecycleState.RESUMED) {
moveToResumedLifecycleState(true);
}
}
}

thanks for you reply

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant