Provides the Android/Gradle functionality to go with https://github.com/react-native-community/react-native-cli/pull/256 & https://github.com/react-native-community/react-native-cli/pull/254
## CLI Changes
- Updated `react-native config` to include the android `sourceDir` for react native module packages
----
## Usage
These are the one-off changes required to enable this in the React Native init template (or for existing user projects).
### Modify `android/settings.gradle`
Include the following line in your Android projects `settings.gradle` file:
```groovy
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
```
### Modify `android/app/build.gradle`
Add the following line at the bottom of your Android projects `android/app/build.gradle` file:
```groovy
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
```
### Modify `MainApplication.java`
Import the PackageList class;
```java
import com.facebook.react.PackageList;
```
Replace the `protected List<ReactPackage> getPackages()` method with the following:
```java
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// additional non auto detected packages can still be added here:
// packages.add(new SomeReactNativePackage());
return packages;
}
```
### Testing
I've tested the following scenarios locally:
- User has no React Native global CLI installed
- Will warn but continue without issue
- User has no React Native packages installed yet
- Continues as normal with no warning
- User has more than one React Native package installed
- Correctly adds multiple packages without issue
- User has a package installed that does not support autodetection (config == null)
- Prints a warning but continues gracefully
- User has custom/non-linked React Native packages
- Can be sucessfully manually added via `packages.add(new SomeReactNativePackage());` as documented above in `MainApplication.java`
To test this in a new `react-native init` project locally:
- Clone the CLI project
- Run `yarn` in the CLI project
- Run `cd packages/cli && yarn && yarn link` in the CLI project
- (a little hacky as it's a mono-repo)
- Run `yarn link "@react-native-community/cli"` on your React Native project
- Make the required changes as above to your React Native project
----
### Codegen Output Example
An example of the generated `PackageList.java` class:
```java
package com.facebook.react;
import android.app.Application;
import android.content.Context;
import android.content.res.Resources;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import java.util.Arrays;
import java.util.List;
import com.test.BuildConfig;
// react-native-webview
import com.reactnativecommunity.webview.RNCWebViewPackage;
public class PackageList {
private ReactNativeHost reactNativeHost;
public PackageList(ReactNativeHost reactNativeHost) {
this.reactNativeHost = reactNativeHost;
}
private ReactNativeHost getReactNativeHost() {
return this.reactNativeHost;
}
private Resources getResources() {
return this.getApplication().getResources();
}
private Application getApplication() {
return this.reactNativeHost.getApplication();
}
private Context getApplicationContext() {
return this.getApplication().getApplicationContext();
}
public List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new RNCWebViewPackage()
);
}
}
```
* Put `isPackagerRunning` function on `cli-tools` to share between iOS & Android
* Fix `terminal` argument not working when not being provided
* Fallback to the default terminal of the machine when starting the packager on `run-android`
* Delete `isPackagerRunning` as it was moved to `tools`
* Add `terminal` argument to `run-ios`
* Launch Metro from within the `runIOS` command
* Remove code & add `—terminal` argument
* Try using `REACT_TERMINAL` before the default terminal
* Put `isPackagerRunning` function on `cli-tools` to share between iOS & Android
* Fix `terminal` argument not working when not being provided
* Fallback to the default terminal of the machine when starting the packager on `run-android`
* Delete `isPackagerRunning` as it was moved to `tools`
* Add `terminal` argument to `run-ios`
* Launch Metro from within the `runIOS` command
* Remove code & add `—terminal` argument
* Try using `REACT_TERMINAL` before the default terminal
* Add tool function to get the default user terminal
* Fix `terminal` arg type
* Remove spread and specify entry twice instead
* Improve `args` being passed through functions
* Reduce code duplication
* Put `device` and `udid` variable up in the scope
Summary:
---------
If we run `react-native run-android` while it's already installed, it will fail with the following error.
```bash
info Installing the app on the device (cd android && adb -s emulator-5554 install app/build/outputs/apk/debug/app-x86-debug.apk
adb: failed to install app/build/outputs/apk/debug/app-x86-debug.apk: Failure [INSTALL_FAILED_ALREADY_EXISTS: Attempt to re-install me.mycake without first uninstalling.]
```
In the development phase, I think using adb's install options below is much more efficient.
```
-r : Reinstall an existing app, keeping its data.
-d : Allow version code downgrade.
```
Test Plan:
----------
Not required.