Skip to content

Commit 369ad10

Browse files
authored
feat: add android support (#49)
* feat(android): add NitroText HybridView implementation - add Android Nitro module with Kotlin view, Fabric state updater, and JNI bridge - share component descriptor/state logic so Fabric can hydrate props on Android - update TypeScript entrypoint, codegen pipeline, and example app for Android support * feat: add support for `onTextLayout` * feat: implement fragment background color support in NitroText
1 parent a213abe commit 369ad10

69 files changed

Lines changed: 3981 additions & 105 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

android/CMakeLists.txt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
project(NitroText)
2+
cmake_minimum_required(VERSION 3.9.0)
3+
4+
set (PACKAGE_NAME NitroText)
5+
set (CMAKE_VERBOSE_MAKEFILE ON)
6+
set (CMAKE_CXX_STANDARD 20)
7+
8+
# Enable Raw Props parsing in react-native (for Nitro Views)
9+
add_compile_options(-DRN_SERIALIZABLE_STATE=1)
10+
11+
# Define C++ library and add all sources
12+
add_library(${PACKAGE_NAME} SHARED
13+
src/main/cpp/cpp-adapter.cpp
14+
)
15+
16+
# Add Nitrogen specs :)
17+
include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/NitroText+autolinking.cmake)
18+
19+
# Set up local includes
20+
include_directories(
21+
"src/main/cpp"
22+
"../cpp"
23+
)
24+
25+
# Add custom ShadowNode implementation
26+
target_sources(
27+
${PACKAGE_NAME} PRIVATE
28+
../cpp/NitroTextShadowNode.cpp
29+
../cpp/NitroTextShadowNode.hpp
30+
../cpp/NitroTextComponentDescriptor.cpp
31+
../cpp/NitroTextComponentDescriptor.hpp
32+
src/main/cpp/NitroTextRegisterProvider.cpp
33+
..
34+
)
35+
36+
find_library(LOG_LIB log)
37+
38+
# Link all libraries together
39+
target_link_libraries(
40+
${PACKAGE_NAME}
41+
${LOG_LIB}
42+
android # <-- Android core
43+
)

android/build.gradle

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
buildscript {
2+
repositories {
3+
google()
4+
mavenCentral()
5+
}
6+
7+
dependencies {
8+
classpath "com.android.tools.build:gradle:8.12.1"
9+
}
10+
}
11+
12+
def reactNativeArchitectures() {
13+
def value = rootProject.getProperties().get("reactNativeArchitectures")
14+
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
15+
}
16+
17+
def isNewArchitectureEnabled() {
18+
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
19+
}
20+
21+
apply plugin: "com.android.library"
22+
apply plugin: 'org.jetbrains.kotlin.android'
23+
apply from: '../nitrogen/generated/android/NitroText+autolinking.gradle'
24+
25+
if (isNewArchitectureEnabled()) {
26+
apply plugin: "com.facebook.react"
27+
}
28+
29+
def getExtOrDefault(name) {
30+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["NitroText_" + name]
31+
}
32+
33+
def getExtOrIntegerDefault(name) {
34+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["NitroText_" + name]).toInteger()
35+
}
36+
37+
android {
38+
namespace "com.nitrotext"
39+
40+
ndkVersion getExtOrDefault("ndkVersion")
41+
compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
42+
43+
defaultConfig {
44+
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
45+
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
46+
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
47+
48+
externalNativeBuild {
49+
cmake {
50+
cppFlags "-frtti -fexceptions -Wall -Wextra -fstack-protector-all"
51+
arguments "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
52+
abiFilters (*reactNativeArchitectures())
53+
54+
buildTypes {
55+
debug {
56+
cppFlags "-O1 -g"
57+
}
58+
release {
59+
cppFlags "-O2"
60+
}
61+
}
62+
}
63+
}
64+
}
65+
66+
externalNativeBuild {
67+
cmake {
68+
path "CMakeLists.txt"
69+
}
70+
}
71+
72+
packagingOptions {
73+
excludes = [
74+
"META-INF",
75+
"META-INF/**",
76+
"**/libc++_shared.so",
77+
"**/libfbjni.so",
78+
"**/libjsi.so",
79+
"**/libfolly_json.so",
80+
"**/libfolly_runtime.so",
81+
"**/libglog.so",
82+
"**/libhermes.so",
83+
"**/libhermes-executor-debug.so",
84+
"**/libhermes_executor.so",
85+
"**/libreactnative.so",
86+
"**/libreactnativejni.so",
87+
"**/libturbomodulejsijni.so",
88+
"**/libreact_nativemodule_core.so",
89+
"**/libjscexecutor.so"
90+
]
91+
}
92+
93+
buildFeatures {
94+
buildConfig true
95+
prefab true
96+
}
97+
98+
buildTypes {
99+
release {
100+
minifyEnabled false
101+
}
102+
}
103+
104+
lintOptions {
105+
disable "GradleCompatible"
106+
}
107+
108+
compileOptions {
109+
sourceCompatibility JavaVersion.VERSION_1_8
110+
targetCompatibility JavaVersion.VERSION_1_8
111+
}
112+
113+
sourceSets {
114+
main {
115+
if (isNewArchitectureEnabled()) {
116+
java.srcDirs += [
117+
// React Codegen files
118+
"${project.buildDir}/generated/source/codegen/java"
119+
]
120+
}
121+
}
122+
}
123+
}
124+
125+
repositories {
126+
mavenCentral()
127+
google()
128+
}
129+
130+
131+
dependencies {
132+
// For < 0.71, this will be from the local maven repo
133+
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
134+
//noinspection GradleDynamicVersion
135+
implementation "com.facebook.react:react-native:+"
136+
137+
// Add a dependency on NitroModules
138+
implementation project(":react-native-nitro-modules")
139+
140+
}
141+
142+
if (isNewArchitectureEnabled()) {
143+
react {
144+
jsRootDir = file("../src/")
145+
libraryName = "NitroText"
146+
codegenJavaPackageName = "com.nitrotext"
147+
}
148+
}

android/gradle.properties

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
NitroText_kotlinVersion=2.0.21
2+
NitroText_minSdkVersion=29
3+
NitroText_targetSdkVersion=34
4+
NitroText_compileSdkVersion=34
5+
NitroText_ndkVersion=27.1.12297006
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
2+
</manifest>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//
2+
// NitroTextRegisterProvider.cpp
3+
// Registers custom ComponentDescriptor for NitroText on Android
4+
//
5+
6+
#include "NitroTextRegisterProvider.hpp"
7+
8+
#include <react/fabric/CoreComponentsRegistry.h>
9+
#include <react/renderer/core/ConcreteComponentDescriptor.h>
10+
#include "../../../cpp/NitroTextComponentDescriptor.hpp"
11+
12+
namespace margelo::nitro::nitrotext {
13+
14+
// Call this from JNI_OnLoad after nitrogen initialization
15+
void registerNitroTextComponentDescriptor() {
16+
using namespace facebook::react;
17+
using margelo::nitro::nitrotext::views::NitroTextComponentDescriptor;
18+
19+
auto provider = concreteComponentDescriptorProvider<NitroTextComponentDescriptor>();
20+
auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
21+
// Add/override provider for component name "NitroText" (HybridNitroTextComponentName)
22+
providerRegistry->add(provider);
23+
}
24+
25+
} // namespace margelo::nitro::nitrotext
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// NitroTextRegisterProvider.hpp
3+
// Declares helper to register custom ComponentDescriptor
4+
//
5+
6+
#pragma once
7+
8+
namespace margelo::nitro::nitrotext {
9+
10+
void registerNitroTextComponentDescriptor();
11+
12+
}
13+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <jni.h>
2+
#include "NitroTextOnLoad.hpp"
3+
#include "NitroTextRegisterProvider.hpp"
4+
5+
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
6+
margelo::nitro::nitrotext::registerNitroTextComponentDescriptor();
7+
return margelo::nitro::nitrotext::initialize(vm);
8+
}

0 commit comments

Comments
 (0)