Русские Блоги
Введение в процесс разработки Android JNI
1. Что такое JNI
Полное название JNI — Java Native Interface, а на китайском он называется Java Native Interface. JNI — это протокол связи между языком JAVA и языком C / C ++. Через JNI код Java может вызывать код, написанный на C, C ++ и других языках, или, наоборот, код C, C ++ и других языков может вызывать код, написанный на Java, через JNI.
Зачем использовать JNI?
Мы знаем, что характеристики языка Java написаны один раз и используются повсюду. Кросс-платформенность — это преимущество Java, но есть свои плюсы и минусы. Кросс-платформенная особенность делает Java и базовые возможности взаимодействия недостаточно сильными, и это язык C / C ++. С другой стороны, в чем она хороша, Java может повторно использовать большое количество существующих файлов библиотеки C / C ++ через JNI, чтобы избежать повторного создания колес.
2. Что такое NDK
Полное название NDK — Native Develop Kit, которое можно перевести в локальный комплект разработчика. NDK — это набор инструментов, предоставляемый Android для разработки на C / C ++.
Какая связь между JNI и NDK?
JNI — это интерфейсный протокол, а NDK — это комплект средств разработки. У них есть одна общая черта: оба языка включают Native (локальный), и все они связаны с языком C / C ++. Тем не менее, немного настаивать на том, что они связаны с этими двумя пунктами. Слишком неохотно. Фактически, JNI — это Java, а NDK — это Android. Между ними нет взаимозависимости. Если есть какие-либо отношения, вы можете использовать NDK для быстрой разработки C / C ++, который соответствует требованиям интерфейса JNI в Android. Динамическая библиотека, удобная для вызовов Java.
Кто-то может спросить, язык разработки Android — это не язык Java, зачем нужны дополнительные средства разработки на языке C / C ++?
Вы знаете, хотя языком разработки Android является Java, ядром является Linux, а основная библиотека Linux написана на C / C ++, поэтому Google предоставляет инструменты NDK для облегчения взаимодействия между разработчиками и основной библиотекой. Однако общая разработка чисто бизнес-приложений не требует использования NDK. Если присутствуют следующие требования, вам необходимо использовать NDK:
- 1. Обеспечьте безопасность кода. Поскольку декомпилировать файл библиотеки so сложно, инкапсуляция основного кода в файл библиотеки so значительно повышает безопасность кода;
- 2. Удобно переносить свои приложения между платформами. С помощью NDK разработчики могут легко создавать динамические библиотеки для указанной платформы;
- 3. Повторно использовать существующую библиотеку с открытым исходным кодом C / C ++;
- 4. Повышение эффективности выполнения программ, особенно для некоторых приложений с интенсивными вычислениями.
3. Процесс разработки JNI
В качестве примера возьмем сложение двух чисел.Сложение двух чисел реализовано в C / C ++, а затем вызывается JNI. Это очень похоже на процесс аутсорсинга в повседневной жизни: Java не хотела делать это сама и отправила запрос на аутсорсинг, и C взял на себя эту работу.
- Первый шаг: первый шаг — выпустить требования для Java. Сначала создайте пакет с именем com.test.jnitest Project, создайте проект с именем JNIUtils из class , И объявите собственный метод в классе. код показан ниже:
nativeКлючевое слово указывает на то, что это функция, которую необходимо передать на аутсорсинг. Затем, после того как C завершит работу по аутсорсингу, в какой форме она будет использоваться для Java, используя файл библиотеки so, а затем Java загружается через System.loadLibrary («jni_method»), имя файла библиотеки sojni_methodЗначение является произвольным, если соответствие между Java и C хорошее.
- Шаг 2: Этот шаг все еще выполняется на стороне Java, и это то, что сделала сторона Java после получения задания C. Функция, которую мы хотим достичь, заключается в том, чтобы ввести два числа в два текстовых поля, нажать кнопку добавления, а затем код вызывает два числа, заполненных буквой C, для добавления функции и отображения результата в интерфейсе. XML-код макета интерфейса выглядит следующим образом :
Вызовите местный дополнительный код в Activity следующим образом:
- Третий шаг: код Java готов. Следующим шагом является передача работы сторонней организации C. Поскольку Java и C являются двумя языками, они не могут напрямую взаимодействовать друг с другом и должны обрабатываться. Процесс взаимодействия: сначала скомпилируйте исходный файл Java, чтобы получить файл .class, щелкнув меню «Сборка» в Visual Studio.Make Project, А затем найдите сгенерированный файл .class по пути, показанному на рисунке ниже. Обратите внимание, что путь несовместим с тем, что сказано в некоторых блогах. Путь к сгенерированному ими файлу .class находится в папке промежуточных классов классов.
-Шаг 4: Создайте файл .class. Язык C по-прежнему не читается, поэтому я сделаю обработку снова. Метод обработки состоит в том, чтобы получить файл заголовка C через файл .class, чтобы язык C мог его понять, и сгенерировать файл заголовка для использованияjavahКоманды можно выполнять в терминале (у меня MAC) или использовать терминал в Android Studio. На самом деле это одно и то же. Сначала войдите в каталог классов в терминале, обратите внимание на каталог классов, иначе вам будет предложено найти файл класса. Моя среда:
/Users/lan/AndroidStudioProjects/JNITest/app/build/intermediates/javac/debug/classesА затем выполните команду:
Примечание. Команда должна содержать полное имя пакета, а файл .class не может иметь суффикс «.class». Кроме того, я сообщал об ошибке, что класс не может быть найден согласно командам других блогов в Интернете, и для решения проблемы добавлен параметр -cp.
После успешного выполнения команды вы можете получить файл .h, как показано на рисунке ниже.
Содержимое созданного файла .h выглядит следующим образом:
-Шаг 5: После получения файла заголовка вы можете реализовать соответствующий код C в соответствии с файлом .h. В каталоге java создайте новую папку jni, скопируйте созданный файл .h в этот каталог, а затем создайте новый файл C с именем JNIUtils, реализуйте функцию, объявленную файлом заголовка в коде, реализация кода выглядит следующим образом:
-Шаг 6: После реализации кода C требования к аутсорсингу для выпуска Java были выполнены. Следующая задача — заставить C передать работу на аутсорсинг в форме, понятной Java. На первом этапе Java уже объяснила это и поручила ему работу. В форме файла библиотеки so следующая задача — найти способ сгенерировать файл библиотеки so. Сначала создайте файл Android.mk в каталоге jni. Функция Android.mk заключается в указании информации о конфигурации для компиляции исходного кода. Содержимое Android.mk выглядит следующим образом:
LOCAL_PATH: = $ (call my-dir), чтобы получить путь, по которому находится сам файл Android.mk, макросmy-dirПредоставляется системой компиляции, возвращает путь к текущему каталогу (каталог, в котором находится сам файл Android.mk);
include $ (CLEAR_VARS) Переменная макроса CLEAR_VARS предоставляется системой компилятора. И укажите на указанный GNU Makefile, который отвечает за очистку LOCAL_xxx вне LOCAL_PATH, например: LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES и т. Д. Зачем вам нужно выполнять эту операцию очистки, потому что все файлы управления компиляцией анализируются и выполняются одной и той же программой GNU Make, а их переменные являются глобальными, и можно избежать взаимного влияния после очистки, поэтому это утверждение должно быть сделано перед описанием каждой библиотеки;
LOCAL_MODULE: = jni_method означает библиотеку, которая будет сгенерирована. Эта библиотека является библиотекой, загруженной в java. Каждое имя библиотеки должно быть уникальным, без пробелов. Система компиляции автоматически добавляет сгенерированное окончательное имя библиотеки.libПрефикс иsoсуффикс. Например, в приведенном выше примере будет сгенерировано имяlibjni_cal.so, Если имя, определенное в LOCAL_MODULE, уже занялоlib, Система сборки не добавитlibПрефикс, например, имя — libmodule, тогда вывод системы компиляции будет libmodule.so вместо liblibmodule.so;
LOCAL_SRC_FILES: = JNIUtils.c содержит список исходных файлов C и / или C ++ для компиляции в библиотеку. Нет необходимости перечислять файлы заголовков. Система компиляции автоматически поможет нам найти зависимые файлы;
include $ (BUILD_SHARED_LIBRARY), где переменная BUILD_SHARED_LIBRARY указывает на сценарий GNU Makefile, который собирает всю информацию, которую вы определили в переменной LOCAL_XXX с момента последнего включения. Этот сценарий определяет, что компилировать и как компилировать:
- BUILD_STATIC_LIBRARY: скомпилирована как статическая библиотека
- BUILD_SHARED_LIBRARY: скомпилирован в динамическую библиотеку
- BUILD_EXECUTABLE: компилировать в исполняемую программу на языке C
- BUILD_PREBUILT: модуль предварительно скомпилирован
Последняя строка справочной системы связывает все вместе:
Седьмой шаг — создать файл Application.mk в каталоге jni с одним предложением: APP_ABI:=all , На предыдущем шаге проблема, которую решает Android.mk, заключается в том, кого компилировать, но еще не решено, для какой платформы скомпилирована. Это работа Application.mk. Общие платформы включают Arm, x86 и MIPS. Метод конфигурацииAPP_ABIВ поле установлено соответствующее значение, например, если вы хотите настроить файл so на основе платформы Arm, тогда APP_ABI := armeabi , Что касается платформы для создания, это зависит от того, на какой платформе будет работать код Java. Я установил его здесь, чтобы настроить поддержку всех платформ, и соответствующее поле APP_ABI := all 。
Восьмой шаг, подготовка к созданию файла so почти завершена, и следующее, что нужно сделать, — это использовать инструмент NDK для создания файла so. Я не буду вдаваться в подробности настройки среды NDK (процесс подбрасывания можно записать в виде блога), здесь предполагается, что среда NDK настроена. Процесс создания NDK очень прост: войдите в каталог jni в терминале, и терминал находится внизу Android Studio. После входа в каталог введите ndk-build После успешной компиляции команды в src / main / появятся еще две папки libs & obj, где libs — это сгенерированный файл библиотеки so, потому что я установил полную платформу в Application.mk, поэтому все платформы сгенерированы Если Application.mk настроен на определенную платформу, будет создан только файл so для конкретной платформы. После получения файла so C может дать Java задание.
Девятый шаг — передать файл библиотеки so на Java. Сначала создайте папку с именем jniLibs в src / main / и поместите папку so, сгенерированную на предыдущем шаге, в этот каталог. Здесь следует отметить два момента, один из которых заключается в том, какие библиотеки нужно копировать, вам нужно увидеть На каких платформах будет работать программа Android, если скопированный файл библиотеки so неверен, приложение не может быть установлено в обычном режиме, и будет запрошена ошибка несоответствия ABI. Поскольку мой эмулятор является платформой x86, я скопировал файл библиотеки so платформы x86 В jniLibs второе заключается в том, что копирование файлов является копией папки вместе, и вы не можете скопировать один файл so в jniLibs.
Десятый шаг, поскольку на первом шаге был подготовлен Java-код, теперь файл библиотеки so также копируется в указанный каталог, Java-код может быть запущен напрямую, на следующем рисунке показан результат работы симулятора.
4. Резюме
Процесс разработки JNI легко понять как аутсорсинг разработки требований между Java и C. Первое — это требование выпуска Java. native Функция объявления ключевых слов реализуется аутсорсингом и объявляет, что задача аутсорсинга передается в виде файла библиотеки so, а задача аутсорсинга Java передается языку C в форме файла заголовка. После того, как язык C будет реализован, мы найдем способ сгенерировать файл библиотеки so для передачи задачи. , И, наконец, скопируйте файл библиотеки so в указанный каталог, Java загрузится нормально, и весь процесс везде завершится.
Источник
Как включить *.so библиотеку в Android Studio?
Я прочитал много потоков, как добавить библиотеку *.so в Android Studio, но никто из них не работает, особенно когда дело доходит до точки текста: это не работает с новым xxx (Android Studio, gradle. )
Мы можем начать с нуля. Я получил:
Android Studio 0.6.0
Из структуры проекта я вижу:
Скомпилируйте Sdk Version 19 Build Tools Версия 19.1.0
Я получил файлы *.so, предварительно скомпилированные, и в демонстрационном приложении они работают. Я должен изменить исходный код приложения, поэтому мне нужно перестроить с теми же файлами *.so.
ОТВЕТЫ
Ответ 1
Создайте новую папку project/app/src/main/jniLibs , а затем поместите ваши файлы *.so со своими папками abi в это местоположение.
Устаревшее решение
Добавьте оба фрагмента кода в свой файл gradle.build в качестве зависимости:
Как создать эту настраиваемую банку:
Тот же ответ можно найти и в связанном с ним вопросе: Включить .so библиотеку в apk в андроид-студии
Ответ 2
Добавление .so Library в Android Studio 1.0.2
- Создать папку «jniLibs» внутри «src/main/»
- Поместите все ваши библиотеки .so внутри папки «src/main/jniLibs»
- Структура папки выглядит,
| —app:
| — | —src:
| — | — | —main
| — | — | — | —jniLibs
| — | — | — | — | —armeabi
| — | — | — | — | — | — | -.
| — | — | — | — | —x86
| — | — | — | — | — | — | -. - Никакой дополнительный код не требует просто синхронизации вашего проекта и запуска вашего приложения.
Ответ 3
*. поэтому библиотека в Android Studio
Вам нужно создать папку jniLibs внутри main в проектах android Studio и поместить все ваши файлы .so внутри. Вы также можете интегрировать эту строку в build.gradle
compile fileTree (dir: ‘libs’, include: [‘.jar’, ‘. so’])
Он отлично работает
Это структура проекта.
Ответ 4
Решение 1. Создание папки JniLibs
Создайте в своем приложении папку «jniLibs» и папки, содержащие ваш *.so внутри. Папка «jniLibs» должна быть создана в той же папке, что и папки «Java» или «Assets».
Решение 2. Модификация файла build.gradle
Если вы не хотите создавать новую папку и сохраняете свои файлы *.so в папке libs, это возможно!
В этом случае просто добавьте файлы *.so в папку libs (пожалуйста, соблюдайте ту же архитектуру, что и решение 1: libs/armeabi/.so) и измените файл build.gradle вашего приложения, чтобы добавить исходный каталог jniLibs.
У вас будет больше объяснений со скриншотами, которые помогут вам здесь (шаг 6):
Ответ 5
Это мой файл build.gradle, обратите внимание на строку
Это будет включать файл libs *.so в apk.
Ответ 6
Чтобы использовать собственную библиотеку (так что файлы) Вам нужно добавить некоторые коды в файл «build.gradle».
Этот код предназначен для очистки каталога «armeabi» и копирования файлов «so» в «armeabi», в то время как «чистый проект».
Ответ 7
Я решил подобную проблему, используя внешние родственные зависимости lib, которые упакованы внутри файлов jar. Иногда эти библиотеки зависимостей архитектуры упаковываются все в одну банку, иногда они разбиваются на несколько файлов jar. поэтому я написал некоторый buildscript для сканирования зависимостей jar для родных libs и сортировки их в правильные папки Android для Android. Кроме того, это также обеспечивает способ загрузки зависимостей, которые не найдены в maven-репозиториях, которые в настоящее время полезны для работы JNA на андроиде, потому что не все родные банки публикуются в публичных репозиториях maven.
Ответ 8
Официальный анонс Android NDK hello-libs Пример CMake
Просто работал у меня на хосте Ubuntu 17.10, Android Studio 3, Android SDK 26, поэтому я настоятельно рекомендую вам основывать свой проект на нем.
Общая библиотека называется libgperf , key code части:
Затем, если вы посмотрите на /data/app на устройстве, там будет libgperf.so .
на С++-коде, используйте: #include
расположение заголовка: hello-libs/distribution/gperf/include/gperf.h
Если вы поддерживаете только некоторые архитектуры, см. Gradle Создание только NDK-цели только ARM
Источник