react-native: Android: Crash after Requesting Bundle

Description

I am following the guide here to integrate React Native with a pre-existing app.

I am doing this via a normal native button. I press this and I execute the setup code in the article.

I see a spinner on the screen and it informs me that the app is “fetching JS bundle”.

Output in the command line bundler also confirms this: [11/14/2016, 4:54:42 PM] <END> Requesting bundle url: /index.android.bundle?platform=android&dev=true&hot=false (327ms)

Unfortunately I then get a crash with the following logcat output:

W/unknown:React(13970): You seem to be running on device. Run 'adb reverse tcp:8081 tcp:8081' to forward the debug server's port to the device. E/AndroidRuntime(13970): FATAL EXCEPTION: AsyncTask #3 E/AndroidRuntime(13970): Process: com.xxxxxxxx, PID: 13970 E/AndroidRuntime(13970): java.lang.RuntimeException: An error occured while executing doInBackground() E/AndroidRuntime(13970): at android.os.AsyncTask$3.done(AsyncTask.java:304) E/AndroidRuntime(13970): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) E/AndroidRuntime(13970): at java.util.concurrent.FutureTask.setException(FutureTask.java:222) E/AndroidRuntime(13970): at java.util.concurrent.FutureTask.run(FutureTask.java:242) E/AndroidRuntime(13970): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) E/AndroidRuntime(13970): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) E/AndroidRuntime(13970): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) E/AndroidRuntime(13970): at java.lang.Thread.run(Thread.java:818) E/AndroidRuntime(13970): Caused by: java.lang.IllegalAccessError: Method 'void android.support.v4.net.ConnectivityManagerCompat.<init>()' is inaccessible to class 'com.facebook.react.modules.netinfo.NetInfoModule' (declaration of 'com.facebook.react.modules.netinfo.NetInfoModule' appears in /data/data/com.xxxx/files/instant-run/dex/slice-com.facebook.react-react-native-0.20.1_b45e38dcf4b17e67a28c8f304d2b842bb0467fc3-classes.dex) E/AndroidRuntime(13970): at com.facebook.react.modules.netinfo.NetInfoModule.<init>(NetInfoModule.java:55) E/AndroidRuntime(13970): at com.facebook.react.shell.MainReactPackage.createNativeModules(MainReactPackage.java:67) E/AndroidRuntime(13970): at com.facebook.react.ReactInstanceManagerImpl.processPackage(ReactInstanceManagerImpl.java:793) E/AndroidRuntime(13970): at com.facebook.react.ReactInstanceManagerImpl.createReactContext(ReactInstanceManagerImpl.java:730) E/AndroidRuntime(13970): at com.facebook.react.ReactInstanceManagerImpl.access$600(ReactInstanceManagerImpl.java:91) E/AndroidRuntime(13970): at com.facebook.react.ReactInstanceManagerImpl$ReactContextInitAsyncTask.doInBackground(ReactInstanceManagerImpl.java:184) E/AndroidRuntime(13970): at com.facebook.react.ReactInstanceManagerImpl$ReactContextInitAsyncTask.doInBackground(ReactInstanceManagerImpl.java:169) E/AndroidRuntime(13970): at android.os.AsyncTask$2.call(AsyncTask.java:292) E/AndroidRuntime(13970): at java.util.concurrent.FutureTask.run(FutureTask.java:237) E/AndroidRuntime(13970): ... 4 more W/ActivityManager( 523): Force finishing activity 1 com.xxxx/com.xxxxxxx.LoginActivity

I have tried:

  • running ‘adb reverse tcp:8081 tcp:8081’ before and after the npm start invocation
  • modifying my app gradle file with various variations of the following:

compile ‘com.android.support:appcompat-v7:23.2.1’ compile ‘com.android.support:appcompat-v7:23.0.1’ compile ‘com.android.support:appcompat-v4:23.0.1’

compile ‘com.facebook.react:react-native:+’ compile ‘com.facebook.react:react-native:0.20.+’

I’m at a bit of a loss as to how to proceed/debug this issue.

Reproduction

Follow guide above.

Hook up guides code to a button is a fairly typical login view.

Press button. Watch spinner popup saying “Requesting JS Bundle”

Confirm in npm start/packager console output.

Watch it crash. Check output in logcat

Additional Information

  • React Native version: compile ‘com.facebook.react:react-native:+’
  • Platform: Android Nexus 7 5.1.1
  • Operating System: MacOS

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 2
  • Comments: 21 (13 by maintainers)

Most upvoted comments

@edo1493 Now that you mentioned RN 0.20.0, I realized what the problem was. This snippet in my gradle file

allprojects {
    repositories {
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
}

had a wrong path to the React Native jars. When gradle can’t find RN in this path, it doesn’t throw an error, but instead looks in maven and finds an old version of it (0.20.0). You can see here that’s the latest version maven has: https://mvnrepository.com/artifact/com.facebook.react/react-native

So that’s why the bundle was failing: the app was using a very old version of RN. It also explains why we didn’t have access to onHostDestroy(), onHostPause() or the ReactApplication class: these were added in newer versions, after 0.20.0.

Fixing the path to the local RN library solved the problem. Now the app is using RN 0.39.2 and the bundle doesn’t fail anymore.

I faced the same problem when trying to integrate RN into an existing app. I followed the guide here but ended up with the undefined is not a function (evaluating '(bridgeConfig.remoteModuleConfig||[]).forEach') crash.

The solution was to create a new RN project from scratch, with the same name as my current app, and then compare what was different between the new project and my existing one. By identifying and correcting these differences, I got my current app to work with RN as intended. Here’s a list of the differences I noticed and the actions I took to fix them:

  1. In my current project, I moved all my files and directories to a new android dir (except for things like README.md and .gitignore).
  2. From the new RN project I created, I copied index.android.js, node_modules and package.json to the root of my existing project.
  3. In the build.gradle file of my existing project’s main module, I added the line apply from: "../../node_modules/react-native/react.gradle". I noticed this line was present in the new RN project, but nothing about it was being said in the documentation link I mentioned above.
  4. In my settings.gradle file, I added the line rootProject.name = '<appname>'. I’m not sure this is needed or not, but it’s there and it’s working.

Other than that, I followed the instructions in the integration guide (like adding the react native gradle line and the maven url). After these steps, the React Native component was rendered successfully without any crashes.

@edo1493 @lucas-tulio these code/configs worked for me in integrating RN v0.39.2 with existing app. I hope it helps.

top-level build.gradle file:

allprojects {
    repositories {
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/node_modules/react-native/android"
        }
    }
}

app-level build.gradle file:

dependencies {
    // React Native
    compile 'com.facebook.react:react-native:0.39.2'
}

MyReactActivity file:

public class MyReactActivity extends Activity implements DefaultHardwareBackBtnHandler {
    private ReactRootView mReactRootView;
    private ReactInstanceManager mReactInstanceManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mReactRootView = new ReactRootView(this);
        mReactInstanceManager = ReactInstanceManager.builder()
                                                    .setApplication(getApplication())
                                                    .setBundleAssetName("index.android.bundle")
                                                    .setJSMainModuleName("index.android")
                                                    .addPackage(new MainReactPackage())
                                                    .setUseDeveloperSupport(BuildConfig.DEBUG)
                                                    .setInitialLifecycleState(
                                                            LifecycleState.RESUMED)
                                                    .build();
        mReactRootView.startReactApplication(mReactInstanceManager, "HelloWorld", null);

        setContentView(mReactRootView);
    }

    @Override
    public void invokeDefaultOnBackPressed() {
        super.onBackPressed();
    }


    @Override
    public void onBackPressed() {
        if (mReactInstanceManager != null) {
            mReactInstanceManager.onBackPressed();
        } else {
            super.onBackPressed();
        }
    }
    @Override
    protected void onPause() {
        super.onPause();

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostPause(this);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostResume(this, this);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (mReactInstanceManager != null) {
            mReactInstanceManager.onHostDestroy(this);
        }
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
            mReactInstanceManager.showDevOptionsDialog();
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }
}