Skip to content

Commit

Permalink
android build: Enable "autolinking".
Browse files Browse the repository at this point in the history
Part of the RN v0.59 -> v0.60 upgrade [1]. (Or, at least, RN and
most library maintainers assume it is done as such.) This must
happen at or after the upgrade because autolinking is a new feature.

"Autolinking" [2] aims to make the "react-native link" command
unnecessary, so that when we add a module with native code, all we
have to do for the module to be included is run `yarn add`. (Other
native-code changes, such as calling functions that the module
provides, may still be necessary.)

So, for Android:

1. As indicated in the doc [2], unlink everything from Android. As
   done in rk-for-zulip/zulip-mobile@6b50b1521, we do this with a
   script, but here, we tell `react-native unlink` to only unlink
   from Android. To be as exhaustive as possible, we tell it to
   unlink *all dependencies* in our package.json. Thankfully, if one
   isn't already linked, unlinking it is a no-op:

   ```
   for dep in `tools/deps`; do
     react-native unlink --platforms=android "$dep"
   done
   ```

   As in rk-for-zulip/zulip-mobile@6b50b1521, it looks like a custom
   script in Sentry removed some setup that we want to remain
   intact. So, exclude these from the commit:

   - In `ios/ZulipMobile.xcodeproj/project.pbxproj`, removing the
     "Upload Debug Symbols to Sentry" PBXShellScriptBuildPhase. We
     don't want to touch the iOS side at all right now.

   - In `android/app/build.gradle`, the removal of the line:

     ```
     apply from: "../../node_modules/@sentry/react-native/sentry.gradle"
     ```

   Strangely, `react-native unlink`'s changes in
   MainApplication.java did not touch the list returned by
   `getPackages`, but it did remove the imports that many of these
   list items depend on. So, remove these list items, taking note,
   for a future step, that a few are left intact:

   - `new MainReactPackage()`
   - `new ZulipNativePackage()`
   - `new NotificationsPackage()`
   - `new SharingPackage()`

2. Apply the Android-side changes from
  facebook/react-native@261197d85. In `getPackages`, this removes
  `MainReactPackage` and gives a new form to put the references to
  `ZulipNativePackage`, `NotificationsPackage`, and
  `SharingPackage`.

3. Now, go back to `react-native-unimodules` [3] and follow the
   "react-native >= 0.60" branch of the "Configure Android"
   instructions. We had to make some trivial changes in
   `MainApplication.java`; we push to the list at the now-existing
   `packages` variable instead of changing the literal list that was
   previously returned without being stored in a variable.

4. Add a `react-native.config.js` file, as the recommended way [2]
   to say we don't want certain modules to be linked. For details on
   `react-native-vector-icons`, see a commit earlier in this series
   that solidified our choice not to link `VectorIconsPackage`.

5. To compare the list of linked packages before and after this
   commit, note that in both cases, the list to be observed is the
   one returned by the `getPackages` implementation in
   `MainApplication.java`.

   Autolinking introduces an auto-generated `PackageList` class in
   `android/app/build/generated/rncli/src/main/java/com/facebook/react/PackageList.java`
   with a `getPackages` method of its own, which helps compose that
   list of packages we're observing. The `getPackages`
   implementation is auto-generated when you build for Android.

   So, compare (by alphebetizing and diffing) the list before
   autolinking with the new list put together with help from that
   auto-generated code.

   They are the same, so, job done.

[1]: https://react-native-community.github.io/upgrade-helper/?from=0.59.10&to=0.60.6

[2]: https://github.com/react-native-community/cli/blob/master/docs/autolinking.md

[3]: https://github.com/unimodules/react-native-unimodules
  • Loading branch information
chrisbobbe authored and gnprice committed Jun 8, 2020
1 parent b09a405 commit f460460
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 68 deletions.
16 changes: 4 additions & 12 deletions android/app/build.gradle
Expand Up @@ -230,18 +230,6 @@ repositories {
}

dependencies {
implementation project(':@react-native-community_async-storage')
implementation project(':@sentry_react-native')
implementation project(':@react-native-community_netinfo')
implementation project(':react-native-document-picker')
implementation project(':react-native-webview')
implementation project(':react-native-text-input-reset')
implementation project(':react-native-image-picker')
implementation project(':react-native-orientation')
implementation project(':react-native-photo-view')
implementation project(':rn-fetch-blob')
implementation project(':react-native-sound')
implementation project(':react-native-device-info')
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.0'
Expand Down Expand Up @@ -279,3 +267,7 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
jvmTarget = "1.8"
}
}

// Necessary for Autolinking; see facebook/react-native@261197d85
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle");
applyNativeModulesAppBuildGradle(project)
52 changes: 20 additions & 32 deletions android/app/src/main/java/com/zulipmobile/MainApplication.java
Expand Up @@ -3,29 +3,18 @@
import android.app.Application;
import android.util.Log;

import com.facebook.react.PackageList;
import com.facebook.hermes.reactexecutor.HermesExecutorFactory;
import com.facebook.react.bridge.JavaScriptExecutorFactory;
import com.RNFetchBlob.RNFetchBlobPackage;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import com.github.yamill.orientation.OrientationPackage;
import com.imagepicker.ImagePickerPackage;
import com.learnium.RNDeviceInfo.RNDeviceInfo;
import com.nikolaiwarner.RNTextInputReset.RNTextInputResetPackage;
import com.reactnative.photoview.PhotoViewPackage;
import com.reactnativecommunity.asyncstorage.AsyncStoragePackage;
import com.reactnativecommunity.netinfo.NetInfoPackage;
import com.reactnativecommunity.webview.RNCWebViewPackage;
import com.zmxv.RNSound.RNSoundPackage;
import io.github.elyx0.reactnativedocumentpicker.DocumentPickerPackage;
import io.sentry.RNSentryPackage;
import java.util.Arrays;
import java.util.List;
import org.unimodules.adapters.react.ModuleRegistryAdapter;
import org.unimodules.adapters.react.ReactModuleRegistryProvider;
import org.unimodules.core.interfaces.SingletonModule;

import com.zulipmobile.generated.BasePackageList;
import com.zulipmobile.notifications.ConversationMap;
Expand All @@ -47,25 +36,24 @@ public boolean getUseDeveloperSupport() {

@Override
protected List<ReactPackage> getPackages() {
return Arrays.asList(
new MainReactPackage(),
new AsyncStoragePackage(),
new NetInfoPackage(),
new DocumentPickerPackage(),
new RNCWebViewPackage(),
new RNTextInputResetPackage(),
new ImagePickerPackage(),
new OrientationPackage(),
new RNSentryPackage(),
new PhotoViewPackage(),
new RNFetchBlobPackage(),
new RNSoundPackage(),
new RNDeviceInfo(),
new ZulipNativePackage(),
new NotificationsPackage(),
new SharingPackage(),
new ModuleRegistryAdapter(mModuleRegistryProvider)
);
// Autolinked packages.
//
// To check what's included, see the
// `getPackages` implementation, which is auto-generated
// (android/app/build/generated/rncli/src/main/java/com/facebook/react/PackageList.java):
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();

// Packages that should be linked, but can't be with
// autolinking:
packages.add(new ZulipNativePackage());
packages.add(new NotificationsPackage());
packages.add(new SharingPackage());

// Unimodules:
packages.add(new ModuleRegistryAdapter(mModuleRegistryProvider));

return packages;
}

@Override
Expand Down
27 changes: 3 additions & 24 deletions android/settings.gradle
@@ -1,31 +1,10 @@
rootProject.name = 'ZulipMobile'

apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle");
applyNativeModulesSettingsGradle(settings)

apply from: '../node_modules/react-native-unimodules/gradle.groovy'
includeUnimodulesProjects()

include ':@react-native-community_async-storage'
project(':@react-native-community_async-storage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/async-storage/android')
include ':@sentry_react-native'
project(':@sentry_react-native').projectDir = new File(rootProject.projectDir, '../node_modules/@sentry/react-native/android')
include ':@react-native-community_netinfo'
project(':@react-native-community_netinfo').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/netinfo/android')
include ':react-native-document-picker'
project(':react-native-document-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-document-picker/android')
include ':react-native-webview'
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
include ':react-native-text-input-reset'
project(':react-native-text-input-reset').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-text-input-reset/android')
include ':react-native-image-picker'
project(':react-native-image-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-image-picker/android')
include ':react-native-orientation'
project(':react-native-orientation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-orientation/android')
include ':react-native-photo-view'
project(':react-native-photo-view').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-photo-view/android')
include ':rn-fetch-blob'
project(':rn-fetch-blob').projectDir = new File(rootProject.projectDir, '../node_modules/rn-fetch-blob/android')
include ':react-native-sound'
project(':react-native-sound').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-sound/android')
include ':react-native-device-info'
project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android')

include ':app'
40 changes: 40 additions & 0 deletions react-native.config.js
@@ -0,0 +1,40 @@
/**
* See https://github.com/react-native-community/cli/blob/master/docs/configuration.md.
*
* To print the full config from the React Native CLI, run
* `react-native config`.
*/
module.exports = {
/**
* See https://github.com/react-native-community/cli/blob/master/docs/dependencies.md.
*
* Currently, we only use this to blacklist some native-code
* libraries, per-platform, that we don't want to be linked with
* "autolinking".
*
* For more about "autolinking", see
* https://github.com/react-native-community/cli/blob/master/docs/autolinking.md.
*/
dependencies: {
'react-native-notifications': {
platforms: {
// We don't use this Wix library in the Android build. See 01b33ad31.
android: null,
},
},
'react-native-screens': {
platforms: {
// We haven't enabled `react-native-screens` yet, that's
// #4111.
android: null,
},
},
'react-native-vector-icons': {
platforms: {
// We're using a setup that doesn't involve linking
// `VectorIconsPackage` on Android.
android: null,
},
},
},
};

0 comments on commit f460460

Please sign in to comment.