Начиная с 1.0.5 в Tracer есть возможность делать часть вызовов в Tracer Android из нативного кода сквозь libtracernative.so
.Под капотом это резолвится в JNI-вызов в Java в основной SDK. Очевидно, делать это именно сквозь libtracernative.so
необязательно, обёртки поставляются для удобства пользования.
Если не собираете свой native-код (например, не используете NDK вообще или используете только предсобранные библиотеки из зависимостей) - нет.
Если вам не нужно инструментировать свой native-код и достаточно просто минидампов на крешах - тоже нет.
В данных случаях достаточно зависимости на ru.ok.tracer:tracer-crash-report-native
в соответствии с быстрым стартом.
Библиотека и заголовочный файл находятся в пакете ru.ok.tracer:tracer-native-bindings
, но требует некоторых осторожностей при подключении.
Инициализация самого "моста" из JNI в Java-Tracer лежит в ru.ok.tracer:tracer-crash-report-native
, т.е. зависимость на него (прямо или транзитивно) в итоговом приложении должна быть.
tracer-crash-report-native
транзитивно подтягивает tracer-native-bindings
, но в силу специфики инструментов этого недостаточно - потребуются более явные манипуляции.
Про Prefab можно почитать здесь.
tracer-native-bindings
пакуется с prefab-модулем tracernative
внутри, AGP сам меняет инвокации ndk-build
/cmake
(добавляет пути для поиска) чтобы он был доступен в Android.mk
/CMakeLists.txt
. На практике на AGP 7.4.1 интеграция с ndk-build
была отломана, так что рекомендуется CMake
prefab
как buildFeature
:android { /* ... */ buildFeatures { prefab = true } }
Добавляем зависимость на ru.ok.tracer:tracer-native-bindings
В CMakeLists.txt появится возможность найти библиотеку и приликноваться к ней
find_package(tracer-native-bindings REQUIRED) target_link_libraries(${YOUR_LIBRARY_NAME} PRIVATE tracer-native-bindings::tracernative)
tracer.h
; ваша библиотека будет собираться с динамической зависимостью на libtracernative.so
При невозможности пользоваться AGP в теории можно инвокать prefab руками, пример здесь
При большом нежелании пользоваться prefab'ом в принципе можно раздирать .aar
-архив руками и выцарапывать из него .so / .h
prefab/modules/tracernative/libs/android.${ARCH}/libtracernative.so
prefab/modules/tracernative/include
#include "tracer.h" /* ... */ void call_to_java_tracer() { tracer_log("log message from native"); tracer_log(u8"лог-сообщение из натива, с юникодом"); tracer_set_key("native_key", "native_value"); } /* ... */
tracer.h
одинаковый с tracer.h
из Tracer Native, большая часть методов оттуда поставляются с пустой имплементацией (можно вызывать, ничего не произойдёт).
Сделано специально чтобы кросплатформенный код с инструментацией Tracer'ом максимально просто кросскомпилировался.
На данный момент из native в Java пробрасываются только два метода:
tracer_log(char* message) -> TracerCrashReport::log
tracer_set_key(char* key, char* value) -> Tracer::setKey
Постепенно будут добавлены другие.
ru.ok.android:tracer-crash-report-native
транзитивно притягивает ru.ok.android:tracer-native-bindings
, но Prefab игнорирует транзитивные зависимости - нужна явная зависимость на tracer-native-bindings
во всех модулях, где планируется использовать JNI-мост.
В CMake, tracer-native-bindings::tracernative
считается IMPROTED-библиотекой - т.е. target_link_libraries(..)
до него подцепляется Android Gradle Plugin'ом и генерирует packaging-конфликт (между libtracernative.so
поднятым как SHARED IMPORTED
и между libtracernative.so
поднятым как jni-либа внутри tracer-native-bindings.aar
).
Решается добавлением pickFirsts
в опции запаковки приложения.
В app/build.gradle.kts
:
android { /* ... */ packaging { jniLibs { pickFirsts += "**/libtracernative.so" } } }