Skip to content

Commit

Permalink
feat/expo rn module (#12)
Browse files Browse the repository at this point in the history
* bring over stuff that looks good from standard native modules attempt

#10

* expo config setup init

MAN THAT WAS HARD!

had to

- downgrade react-native to 0.71
- upgrade kotlin to 1.8
- downgrade gradle to 7.6
- change the location of @react-native/gradle-plugin  to
  react-native-gradle-plugin
- setup the expo config to use the hermes compiler (not mention in doc
    :/ )

facebook/react-native#38179

expo/expo#22008

* missed a spot

* got everything running with no errors

ran into this ugly one called

java.lang.IllegalStateException: Current Activity is of incorrect class,
expected AppCompatActivity, received ui.MyReactActivity

hard to debug for real for real.

ended up looking into expo docs that said they are getting rid of the
bare instructions

and then

expo/expo#18022

then that had me be like where is that erorr even from...

which lead me to git blame

packages/expo-modules-core/android/src/main/java/expo/modules/kotlin/AppContext.kt

which lead me to

expo/expo#19573

which lead me to

s/Activity/AppCompatActivity/g

in

android/app/src/main/java/com/github/quarck/calnotify/ui/MyReactActivity.kt

* fix: forgot to switch to matching gradle version for android build plugin

* def don't need react native picker

hope we don't need expo install modules either

* kinda crazy but got a (mostly) WORKING NATIVE MODULE!

in

modules/my-module/android/src/main/java/expo/modules/mymodule/MyModule.kt

Constants, Events, and AsyncFunction work beautifully!

View seems to work but I don't really understand it

weirdly Function DOES NOT WORK AT ALL!!!

it just says is not a function and since it seemed like the easiest
thing and was what I looked at first it made me thing everything else
was broken too :/

lost A LOT of time to that

* Logcat instead of println and hello on button press

* document why chrome debugging doesn't work as expected by default

to save myself time in the future

* debugging with vscode works!!!!

unfortunately debugging syncronous native modules in it does not :/

* more docs on debugging

* react-native-devsettings because why not

* flipper setup again because why not?

* drop a android studio thing that didn't work

* fix readme

* drop a dependency we dont need that had a peer dependency that broke shit

expo-module-scripts 3.1.0 depends on @expo/config 7.5 which breaks shit

* Revert "flipper setup again because why not?"

turns out it breaks build. like flipper but not worth build break

This reverts commit 8612ff3.

* do still want to set entryFile though
  • Loading branch information
williscool authored Oct 14, 2023
1 parent 68cf15d commit 31b3a5c
Show file tree
Hide file tree
Showing 34 changed files with 4,847 additions and 784 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ dist
# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# vscode react native debug
.vscode/.react

# yarn v3
.pnp.*
.yarn/*
Expand Down
23 changes: 23 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Sources
// https://gist.github.com/bergmannjg/461958db03c6ae41a66d264ae6504ade?permalink_comment_id=3737831#debug-app-in-visual-studio-code-from-wsl2
{
"configurations": [
{
"name": "(my) Attach to packager",
"cwd": "${workspaceFolder}",
"type": "reactnative",
"request": "attach"
},
// what I really want to debug is the hermes engine though which is gonna take this setup
// https://marketplace.visualstudio.com/items?itemName=msjsdiag.vscode-react-native#hermes-engine
//
// but sadly spent a day on trying to get hermes debugging going and it don't work :/ see README.md for more info
// long story short it doesnt work in dev mode, only release mode and I couldn't get a relase build to work locally to test it
{
"name": "ONLY WORKS AGAINST A ANDROID RELEASE BUILD- Hermes Attach application - Experimental",
"cwd": "${workspaceFolder}",
"type": "reactnativedirect",
"request": "attach",
}
]
}
1 change: 1 addition & 0 deletions .watchmanconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
99 changes: 92 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,102 @@ cd C:\Users\<username>\appdata\local\android\sdk
.\emulator\emulator.exe -avd 7.6_Fold-in_with_outer_display_API_34q
```

## Wsl setup
## Setting up adb

https://gist.github.com/bergmannjg/461958db03c6ae41a66d264ae6504ade?permalink_comment_id=4149833#gistcomment-4149833

```bash
sudo ln -s /mnt/c/Users/<username>/AppData/Local/Android/Sdk/platform-tools/adb.exe /home/<username>/android/platform-tools/adb
```

## Wsl metro connection setup

```bash

# get the wsl2 ip address
ifconfig eth0 | grep 'inet '
# Get the WSL2 IP address and store it in a variable
WSL_VM_IP_ADDRESS=$(ifconfig eth0 | awk '/inet / {print $2}')

# Get the Windows HOST IP address and store it in a variable (in case you need it)
HOST_IP_ADDRESS=$(ipconfig.exe | awk '/Ethernet adapter vEthernet \(Default Switch\):/{i=1; next} i && /IPv4 Address/{print $NF; exit}' | sed 's/^[ \t]*//')

# open the developer menu in the react native activity once loaded
./adb.exe shell input keyevent 82
# Open the developer menu in the React Native activity once loaded
adb shell input keyevent 82

# Input the IP address in the developer menu
adb shell input text "${WSL_VM_IP_ADDRESS}:8081"

# input the aformentioned ip address in the developer menu
./adb.exe shell input text "172.21.60.143:8081"

```


## Debugging

WARNING: BY DEFAULT IN THE CHROME DEBUGGER Expo Module Function does not work AT ALL! https://docs.expo.dev/modules/module-api/#function

(WHY THIS ISNT IN BIG BOLD RED LETTERS AS A NOTE ON THE DOCUMENTATION FOR SYNC FUNCTIONS IS BEYOND ME!)

this is because either the methods are using @ReactMethod(isBlockingSynchronousMethod = true)

https://reactnative.dev/docs/native-modules-android#synchronous-methods

and or JSI, a JavaScript interface for native code, is being used which requires the JS VM to share memory with the app.

For the Google Chrome debugger, React Native runs inside the JS VM in Google Chrome, and communicates asynchronously with the mobile devices via WebSockets.

So it wont have access to the native modules.

Alternative setups:

Hermes on Chrome - https://reactnative.dev/docs/hermes?package-manager=yarn#debugging-js-on-hermes-using-google-chromes-devtools

VSCode - https://marketplace.visualstudio.com/items?itemName=msjsdiag.vscode-react-native

Flipper - https://fbflipper.com/


LOST A LOT OF TIME ON THIS! so wanted to document it here.

Sources:
https://github.com/williscool/CalendarNotification/issues/13#issuecomment-1760712053
https://reactnative.dev/docs/native-modules-android?android-language=kotlin#synchronous-methods

## Debugging Hermes on Chrome

WARNING: THIS DOES NOT WORK IN DEVELOPMENT MODE! YOU MUST BUILD YOU ANDROID APP IN RELEASE MODE!
(WHY THIS ISNT IN BIG BOLD RED LETTERS AS A NOTE ON THE DOCUMENTATION FOR DEBUGGING HERMES IS BEYOND ME!)

the instructions do say to to do a release build, but it doesnt say that it wont work in development mode!

if you want to try to get to work these gusy https://github.com/gusgard/react-native-devsettings

are working on it
https://github.com/jhen0409/react-native-debugger/issues/573#issuecomment-1533894331


Sources:
- google: react native hemes dev tools
- https://stackoverflow.com/questions/76604735/expo-v48-remote-debugging-w-hermes


## Building

### Debug

works like normal

### Release Local


https://instamobile.io/android-development/generate-react-native-release-build-android/

build the bundle ahead of time

```
yarn react-native bundle --platform android --dev false --entry-file index.tsx --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/
```

Android studio instructions: https://stackoverflow.com/questions/18460774/how-to-set-up-gradle-and-android-studio-to-do-release-build


### Release CI
see .github/workflows/actions.yml
6 changes: 5 additions & 1 deletion android/.idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 13 additions & 3 deletions android/.idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion android/.idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions android/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions android/.idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 10 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ apply plugin: "com.facebook.react"
//

android {
compileSdkVersion 31
buildToolsVersion '31.0.0'
compileSdkVersion 34

defaultConfig {
applicationId "com.github.quarck.calnotify"
Expand Down Expand Up @@ -51,8 +50,11 @@ android {
main.java.srcDirs += 'src/main/kotlin'
}
namespace 'com.github.quarck.calnotify'


}


dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])

Expand All @@ -71,4 +73,10 @@ dependencies {
implementation 'com.google.android.material:material:1.0.0-rc01'
}

// https://reactnative.dev/docs/react-native-gradle-plugin
react {
entryFile = file("../../index.tsx")
}


apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@

package com.github.quarck.calnotify

import android.app.Application;
import android.content.Context

// This storage is wiped every time app is restarted. Only keep variables
// that are instance-specific here
class GlobalState : android.app.Application() {
class GlobalState : Application() {
var lastNotificationRePost: Long = 0
var lastTimerBroadcastReceived: Long = 0
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.github.quarck.calnotify.ui
import android.app.Activity
import android.os.Bundle
import android.view.KeyEvent
import androidx.appcompat.app.AppCompatActivity
import com.facebook.react.BuildConfig
import com.facebook.react.PackageList
import com.facebook.react.ReactInstanceManager
Expand All @@ -11,7 +11,9 @@ import com.facebook.react.common.LifecycleState
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler
import com.facebook.soloader.SoLoader

class MyReactActivity : Activity(), DefaultHardwareBackBtnHandler {


class MyReactActivity : AppCompatActivity(), DefaultHardwareBackBtnHandler {
private lateinit var reactRootView: ReactRootView
private lateinit var reactInstanceManager: ReactInstanceManager
override fun onCreate(savedInstanceState: Bundle?) {
Expand Down Expand Up @@ -68,4 +70,6 @@ class MyReactActivity : Activity(), DefaultHardwareBackBtnHandler {
}
return super.onKeyUp(keyCode, event)
}


}
4 changes: 2 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext.kotlin_version = '1.7.20'
ext.kotlin_version = '1.8.20'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.1.2'
classpath 'com.android.tools.build:gradle:7.4.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath("com.facebook.react:react-native-gradle-plugin")

Expand Down
1 change: 1 addition & 0 deletions android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ android.useAndroidX=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false
hermesEnabled=true
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
7 changes: 5 additions & 2 deletions android/settings.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
include ':app'
includeBuild('../node_modules/@react-native/gradle-plugin')
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
includeBuild('../node_modules/react-native-gradle-plugin')
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)

apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle")
useExpoModules()
Loading

0 comments on commit 31b3a5c

Please sign in to comment.