Как говорится в заголовке - как добавить собственный код в существующий проект Android Studio, не нарушая текущий проект, включая gradle и настройки proguard?
Как добавить JNI (собственный код C/С++) в существующий проект Android Studio
Ответ 1
Выполните следующие действия из вашего существующего проекта:
1. Измените build.gradle (приложение-модуль), чтобы оно выглядело так (много изменений!):
apply plugin: 'com.android.model.application'
model {
android.signingConfigs {
create ("myConfig") {
keyAlias '--your-key-alias--'
keyPassword '--key-password--'
storeFile file('--/path/to/keystore.jks--')
storePassword '--store-password--'
}
}
android {
compileSdkVersion 25
buildToolsVersion '25.0.2'
defaultConfig {
applicationId "--your.app.name--"
minSdkVersion.apiLevel 19
targetSdkVersion.apiLevel 25
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled true
proguardFiles.add(file('proguard-android-optimize.txt'))
proguardFiles.add(file('proguard-rules.pro'))
signingConfig = $("android.signingConfigs.myConfig")
}
}
ndk {
moduleName "--c-file--"
ldLibs.addAll(["android", "log"])
}
}
android.dexOptions {
javaMaxHeapSize "2048m"
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:25.3.1'
}
Вы можете скопировать/вставить приведенный выше код и изменить, по крайней мере, значения с помощью "--value--", чтобы они соответствовали вашим.
2. Измените build.gradle (Проект)
где написано примерно так:
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
}
к этому:
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.9.3'
}
Число в моем примере 0.9.3 - последняя версия gradle-экспериментальной, которую можно найти здесь. В конце концов измените версию Gradle в gradle-wrapper.properties на версию, рекомендованную Android Studio, если вы этого еще не сделали.
3. Переместите ваш файл настроек Proguard
proguard-android-optimize.txt
в app/proguard-android-optimize.txt
4. Добавить звонок из Java
как это
static {
System.loadLibrary("--c-file--");
}
private native byte my_jni(Context context, byte[] mByte, int i);
меняется в соответствии с вашими потребностями. В приведенном выше примере загружается c файл (запишите его без расширения) - тот же, который объявлен в файле gradle, и вызывает функцию my_jni, передавая контекст приложения, некоторый байтовый массив и некоторый int, ожидая, что функции возвращают байт,
5. Создайте функцию в JNI:
Теперь название вашей функции выделено красным - позвольте Android Studio создать его. Create function...
нажав на красную лампочку в строке. Это создает функцию в вашем файле c и меняет фокус на нее.
Готово
Дальнейшее чтение здесь.
Подсказки:
-
Позаботьтесь о том, чтобы
free
все, что вы используетеmalloc
,ReleaseByteArrayElements
для каждогоGetByteArrayElements
и т.д. -
Позаботьтесь о том, как правильно вернуть некоторые опасные значения из C в Java, такие как массивы и строки
Ответ 2
Начиная с Android Studio 3.1 это возможно простым способом:
1. Создайте папку cpp
внутри app\src\main
.
2. Создайте файл <YOUR_FILE_NAME>.cpp
папке app\src\main\cpp
(например, native-lib.cpp).
3. Добавьте файл CMakeLists.txt
в папку app
.
В этом имени файла библиотеки должны быть определены путь к файлу .cpp
и некоторые другие параметры, например (из нового пустого Android Studio Project с поддержкой C++):
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp )
^^^^^^^^^^^^^^
YOUR_CPP_FILE_NAME
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
4. Добавьте в build.gradle (приложение-модуль) тег externalNativeBuild
со ссылкой на CMakeLists.txt
в раздел android
:
android {
compileSdkVersion 26
defaultConfig {
...
}
buildTypes {
...
}
externalNativeBuild { <--- these lines should be added
cmake { <--- these lines should be added
path "CMakeLists.txt" <--- these lines should be added
} <--- these lines should be added
} <--- these lines should be added
}
5. Добавьте в build.gradle (приложение-модуль) тег externalNativeBuild
тегом cmake
в раздел defaultConfig
:
...
defaultConfig {
applicationId "<YOUR_APP_ID>"
minSdkVersion 26
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild { <--- these lines should be added
cmake { <--- these lines should be added
cppFlags "" <--- these lines should be added
} <--- these lines should be added
} <--- these lines should be added
}
...
(пример "базового" файла build.gradle
также доступного в новом, пустом проекте Android Studio с поддержкой C++)
6. Resync Project с файлами Gradle
Нажав Sync Project на панели инструментов. NB! В Android Studio 3.3 это значок .
Кроме того, взгляните на официальный учебник.