Разработка Native Module для React Native (Android)

Разработка Native Module для React Native-приложения (Android) Представьте: вы подключаете к React Native приложению специфичное Bluetooth-устройство, но стандартные библиотеки не дают нужного уровня контроля. JavaScript не может напрямую вызвать Android API — нужен Native Module. Ошибка в его ре

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Разработка Native Module для React Native (Android)
Сложный
~3-5 дней

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    597

Разработка Native Module для React Native-приложения (Android)

Представьте: вы подключаете к React Native приложению специфичное Bluetooth-устройство, но стандартные библиотеки не дают нужного уровня контроля. JavaScript не может напрямую вызвать Android API — нужен Native Module. Ошибка в его реализации приведёт к крашу приложения или утечке памяти. За 5 лет работы мы выполнили более 30 проектов с Native Modules и знаем типичные ловушки. Разберём на примере Bluetooth LE.

Native Module — это мост между JS и нативным кодом Android. React Native предлагает два подхода: классический Bridge и новый TurboModule на основе JSI. Выбор архитектуры напрямую влияет на скорость работы: TurboModule обеспечивает latency 1–2 мс против 10–20 мс у Bridge, что даёт выигрыш до 10 раз для высокочастотных вызовов. Эта разница заметна при непрерывном потоке данных (аудио, датчики).

Реализация Bridge-модуля

Для проектов, использующих старую архитектуру (без поддержки JSI), применяйте классический подход.

// BluetoothModule.kt class BluetoothModule(private val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { override fun getName(): String = "BluetoothModule" @ReactMethod fun isBluetoothEnabled(promise: Promise) { val bluetoothManager = reactContext.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager promise.resolve(bluetoothManager.adapter?.isEnabled ?: false) } @ReactMethod fun startScan(promise: Promise) { val scanner = (reactContext.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager) .adapter?.bluetoothLeScanner if (scanner == null) { promise.reject("BT_ERROR", "Bluetooth LE not supported") return } promise.resolve(null) } private fun sendEvent(eventName: String, params: WritableMap?) { reactContext .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) .emit(eventName, params) } } 

Зарегистрируйте модуль через ReactPackage и добавьте его в MainApplication.kt в метод getPackages().

Как выбрать между Bridge и TurboModule?

Критерий Bridge (старая архитектура) TurboModule (новая архитектура)
Производительность Вызов через JSON-сериализацию, latency ~10-20 мс JSI без сериализации, latency ~1-2 мс
Совместимость Проекты без поддержки JSI Проекты с новой архитектурой (JSI)
Поддержка Устаревает, но ещё широко используется Будущее React Native, активная разработка
Сложность Проще, не требует Codegen Требует TypeScript спецификацию и генерацию кода

Для высокочастотных вызовов (аудио, датчики) TurboModule даёт выигрыш в производительности до 10 раз. Затраты на разработку такого модуля окупаются за счёт снижения времени доработок на 30%.

Почему TurboModule быстрее Bridge?

TurboModule использует JSI (JavaScript Interface) для прямого вызова нативных функций, минуя JSON-сериализацию. Bridge же каждый вызов упаковывает в JSON, что добавляет накладные расходы. Для одиночных вызовов разница незаметна, но при 1000 вызовов в секунду TurboModule экономит до 20 мс — критично для анимаций или обработки датчиков.

Как передавать события из нативного кода в JS?

Паттерн един для обеих архитектур — используйте RCTDeviceEventEmitter.

fun emitScanResult(deviceAddress: String, rssi: Int) { val params = Arguments.createMap().apply { putString("address", deviceAddress) putInt("rssi", rssi) } reactApplicationContext .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) .emit("onBluetoothDeviceFound", params) } 

На JS подписывайтесь через NativeEventEmitter:

import { NativeEventEmitter, NativeModules } from 'react-native'; const { BluetoothModule } = NativeModules; const emitter = new NativeEventEmitter(BluetoothModule); useEffect(() => { const subscription = emitter.addListener('onBluetoothDeviceFound', (event) => { console.log('Found device:', event.address, 'RSSI:', event.rssi); }); return () => subscription.remove(); }, []); 

Обязательно вызывайте subscription.remove() в cleanup — утечка подписки приведёт к вызову обработчика после размонтирования компонента.

Запрос разрешений: ответственность JS-слоя

Нативный модуль не должен самостоятельно запрашивать runtime-разрешения — это ответственность JS-слоя через react-native-permissions или PermissionsAndroid. Модуль только проверяет наличие и возвращает ошибку. Например, если разрешение BLUETOOTH_SCAN не выдано, модуль вернёт ошибку PERMISSION_DENIED.

Использование Codegen для TurboModule

При использовании TurboModule требуется создать TypeScript-спецификацию и запустить Codegen. Это автоматически генерирует Kotlin-интерфейсы и JNI-код. Пример:

export interface Spec extends TurboModule { readonly getConstants: () => { [key: string]: any }; isBluetoothEnabled(): Promise<boolean>; startScan(): Promise<void>; } 

Codegen сокращает время реализации на 30% и исключает ошибки ручного связывания.

Тестирование модуля

Нативный модуль тестируется на уровне Kotlin (JUnit + Mockk) и на уровне интеграции через Detox. Например, проверка возврата false при отсутствии Bluetooth:

@Test fun `isBluetoothEnabled returns false when adapter is null`() { val context = mockk<ReactApplicationContext>() every { context.getSystemService(Context.BLUETOOTH_SERVICE) } returns mockk<BluetoothManager> { every { adapter } returns null } val module = BluetoothModule(context) val promise = mockk<Promise>(relaxed = true) module.isBluetoothEnabled(promise) verify { promise.resolve(false) } } 

Также важно тестировать обработку ошибок и жизненный цикл. Благодаря модульным тестам клиенты экономят до 30% бюджета на отладке.

Типичные ошибки при разработке

  • Утечка контекста: не храните ссылку на ReactApplicationContext в статическом поле — используйте WeakReference.
  • Игнорирование ProGuard: добавьте правила -keep для вашего модуля, иначе продакшн-сборка упадёт с ClassNotFoundException.
  • Смешивание архитектур: не используйте Bridge-методы в TurboModule-проекте — нарушится подпись.

Что входит в разработку нативного модуля

Компонент Описание
Спецификация API TypeScript интерфейс для Codegen (если TurboModule) или объявление методов для Bridge
Нативная реализация Класс модуля на Kotlin с обработкой всех кейсов
Юнит-тесты Тестирование модуля на Kotlin с mock зависимостей
Интеграция в проект Настройка Package, разрешений и Gradle
Документация API, примеры, обработка ошибок
Поддержка после сдачи 30 дней на исправление багов

Процесс работы

  1. Анализ требований — изучаем Android API, согласуем сигнатуры методов.
  2. Проектирование спецификации — создаём TypeScript интерфейс или JS-прокси.
  3. Реализация нативного кода — пишем модуль на Kotlin, обрабатываем edge cases.
  4. Тестирование — юнит-тесты + интеграция в проект-пример.
  5. Интеграция и документирование — подключаем к вашему приложению, обновляем документацию.
  6. Передача — исходники, демо-проект, инструкция по сборке.

Сроки: базовый модуль с 3-5 методами — 2-4 дня; модуль с событиями и тестами — от недели. Стоимость рассчитывается индивидуально. Закажите консультацию — получите точную оценку вашего проекта и бесплатный анализ требований. Свяжитесь с нами в течение рабочего дня.