I am doing every single step from video:
https://www.youtube.com/watch?v=kFtxo7rr2HQ
but no shared libraries are generated.
Here is a version, where android-studio should generate shared libraries on his own. However when I create apropraite Makefiles and execute ndk-build, shared libraries are not generated as well.
MainActivity.java:
public native String HelloJNI();
static
{
System.loadLibrary("HelloJNI");
}
Build->Make Project
[*#* main]$ javah -d jni -classpath {sdk_dir}/platforms/android-14/android.jar:../../build/intermediates/classes/debug com.example.ndker.ndkapp.MainActivity
Creating HelloJNI.c:
#include "com_example_ndker_ndkapp_MainActivity.h"
JNIEXPORT jstring JNICALL Java_com_example_ndker_ndkapp_MainActivity_HelloJNI
(JNIEnv *, jobject) {
return (*env)->NewStringUTF(env, "Hello from jni");
}
local.properties:
sdk.dir={sdk_dir}
ndk.dir={ndk_dir}
build.grandle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.example.ndker.ndkapp"
minSdkVersion 14
targetSdkVersion 21
versionCode 1
versionName "1.0"
ndk {
moduleName "HelloJNI"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
}
Thank You for replies.
I've created a blog post that documents setting up Android Studio, Gradle, and the NDK here:
http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/
Also, I've created a sample project in BitBucket with everything already set up for you here: https://bitbucket.org/sureshjoshi/android
Perhaps you could give those a try and see if they work for you?
The key thing is that Gradle will now automatically generate Makefiles and compile for you!
Right. If you put the video on HD, you can then realize that to generate the native compilation, you should use ";" instead of ":". Like:
[*#* main]$ javah -d jni -classpath {sdk_dir}/platforms/android-14/android.jar;../../build/intermediates/classes/debug com.example.ndker.ndkapp.MainActivity
Here is an screenshot of the screen (taken from the video you've posted)
Let me know if that did the trick!
Related
I cannot get an Android Wear project to use C++. I am able to get a "Phone and Tablet" project to use C++. Here is what I have done.
Here is an image of the SDK Tools I have installed. I also have SDK API Levels 24-27 installed.
I create a new project. I check "Include C++ support". I check "Wear" (API 26: Android 8.0 (Oreo)). I select "Next" a bunch.
For C++ Standard I have tried all three (Toolchain Default, C++11, c++14).
I do not check -fexceptions or -frtti.
In the project that is created under the "mobile" Module, I have a "cpp" folder, but I do not have one under the "wear" Module.
If I create a project without "Phone and Tablet" support ("mobile" Module), then I still do not get a "cpp" folder under the "wear" Module.
I tried forcing the project to use C++ under the "wear" Module. Here is what I did.
I modified build.gradle (Module: wear) to look like this
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.example.xorgaming.watchtestcpp"
minSdkVersion 25
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-std=c++11"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.google.android.support:wearable:2.2.0'
implementation 'com.google.android.gms:play-services-wearable:11.8.0'
implementation 'com.android.support:percent:26.1.0'
implementation 'com.android.support:support-v4:26.1.0'
implementation 'com.android.support:recyclerview-v7:26.1.0'
implementation 'com.android.support:wear:26.1.0'
compileOnly 'com.google.android.wearable:wearable:2.2.0'
}
I restart the project which makes a "cpp" folder under the "wear" module.
I create a native-lib.cpp file in the "cpp" folder. It looks like this:
extern "C"
JNIEXPORT jstring JNICALL Java_com_example_xorgaming_watchtestcpp_MainActivity_stringFromJNIWatch(
JNIEnv *env, jobject /* this */)
{
std::string hello = "Hello from C++ WATCH!";
return env->NewStringUTF(hello.c_str());
}
In my java onCreate() function, I call: stringFromJNIWatch().
Everything builds without error (green hammer)
When I run the project (as a wearable device) I get this error:
No implementation found for java.lang.String com.example.xorgaming.watchtestcpp.MainActivity.stringFromJNIWatch()
Any idea what I'm doing wrong? Does Android Wear support C++?
Things have changed quite a bit since this question was posted. But half of the answer is: Yes, you can use C++ and Java together with Wear OS. You can follow the same instructions for Android applications.
As for why this failed, my suggestion would be double-check the paths. If you follow the instructions here you will note that the cpp directory goes in the same directory with the java directory. Typically something like MyApplication/app/src/main will have a java directory and a cpp directory. That helps everything get wrapped up into the eventual .apk
I was trying to create a simple project to test the NDK in which a jnilib uses a prebuilt .so library but I keep getting an UnsatisfiedLink error:
With emulator:
java.lang.UnsatisfiedLinkError: dlopen failed: library "~/AndroidStudioProjects/HelloAndroidJni/app/src/main/jni/libs/dynamic/x86/libadd.so" not found
With actual device:
Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1891]: 1675 could not load needed library '~/AndroidStudioProjects/HelloAndroidJni/app/src/main/jni/libs/dynamic/armeabi/libadd.so' for 'libhello-android-jni.so' (load_library[1093]: Library '~/AndroidStudioProjects/HelloAndroidJni/app/src/main/jni/libs/dynamic/armeabi/libadd.so' not found)
The .so library has a single function "add" which adds 2 numbers. I compiled it with the NDK standalone toolchain for different ABI (doc):
add.c
#include "add.h"
int add(int x, int y){
return x + y;
}
My jni (.c file):
#include <jni.h>
#include "add.h"
JNIEXPORT jint JNICALL
Java_com_example_tomas_helloandroidjni_MainActivity_addNumbersJni(JNIEnv *env, jobject instance,
jint n1, jint n2) {
return add(n1, n2);
}
My files structure looks like this:
And my gradle file (as defined in the experimental gradle guide):
apply plugin: 'com.android.model.application'
model {
repositories {
libs(PrebuiltLibraries) {
libadd{
headers.srcDir "src/main/jni/prebuilts/include"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("src/main/jni/libs/dynamic/${targetPlatform.getName()}/libadd.so")
}
}
}
}
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
sources {
main {
jni {
dependencies {
library "libadd" linkage "shared"
}
}
}
}
ndk {
moduleName = "hello-android-jni"
debuggable = true
}
defaultConfig.with {
applicationId = "com.example.tomas.helloandroidjni"
minSdkVersion.apiLevel = 15
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
}
buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file("proguard-android.txt"))
}
}
productFlavors {
create ("x86"){
ndk.abiFilters.add("x86")
}
create("arm"){
ndk.abiFilters.add("armeabi")
}
create("arm7"){
ndk.abiFilters.add("armeabi-v7a")
}
create ("fat"){
}
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.2.0'
}
I'm not sure where to look at, as I keep getting this error... Maybe I need to add a flag or something?
Thanks in advance for any advice!
EDIT 1.
I tried with static libraries and they work fine. As a consequence (of adding the static libs) I changed the folders' structure slightly (modifying the gradle file accordingly).
I'm working on both:
Actual device: Samsung GT-I8190L Android 4.1.2, API 16 - ARMv7 Processor rev 1 (v7l)
Emulator: Nexus 4 API 23 - x86
EDIT 2.
To compile the libraries I'm doing it with the NDK Standalone Toolchain:
Actual device (ARMv7): SYSROOT=$NDK/platforms/android-21/arch-arm and CC="$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc-4.8 --sysroot=$SYSROOT"
Emulator (x86): SYSROOT=$NDK/platforms/android-21/arch-x86 and CC="/Users/Tomas/Library/Android/android-ndk-r10e/toolchains/x86-4.8/prebuilt/darwin-x86_64/bin/i686-linux-android-gcc-4.8 --sysroot=$SYSROOT"
This may not be the way these native dependencies were expected to work, but (update: this is implicitly written in the doc!) even with plugin 0.7.0, gradle does not copy libadd.so to the APK. There is a workaround, though; add to build.gradle the enchantment:
model {
android.sources.main {
jniLibs.source.srcDir 'src/main/jni/libs/dynamic'
}
}
Still, I recommend to move libs/dynamic folder out of the jni sources folder.
Android Studio 1.1 generated apk file (located # app/build/outputs/apk folder) contains the lib directory, and for every cpu type there exists a non-empty folder, like /x86. Each of these folder contain a libapp.so shared library that is around 5Kb in size per cpu.
I've searched the net and the only thing I found so far is this link from Intel https://software.intel.com/en-us/articles/building-native-android-apps-using-intelr-c-compiler-in-android-studio that shows how to change the default libapp.so to user-provided library.
So, I guess that this library (libapp.so) is somehow built by gradle.
In fact I do my own native library building, using ndk-build command line tool, and my libs are placed alongside that libapp.so. It's not causing any issues btw, but I feel that I'm losing the control over what is built and why.
Here's my humble build.gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
/**
* Path to *.so files
*/
sourceSets {
main {
jniLibs.srcDirs = ['src/main/libs']
jni.srcDirs = [] //disable automatic ndk-build
}
}
defaultConfig {
applicationId "com.sample.android"
minSdkVersion 9
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
}
How can I disable this libapp.so being built?
defaultConfig {
ndk {
moduleName "yourSelfLib"
}
}
I need to develop an audio app in NDK using Android Studio. I have added
the ndk path to local.properties -
ndk.dir=/opt/android-ndk-r10
sdk.dir=/opt/adt-bundle-linux-x86_64-20140702/sdk
In build.gradle I added an entry for OpenSLES -
apply plugin: 'com.android.application'
android {
compileSdkVersion 20
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.example.hellojni"
minSdkVersion 8
targetSdkVersion 21
ndk {
moduleName "HelloJNI"
ldLibs "OpenSLES" // Link with these libraries!
stl "stlport_shared"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile 'com.android.support:support-v4:20.0.0'
compile 'com.android.support:appcompat-v7:20.0.0'
}
Next I tried to add #includes for opensl -
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
but the IDE is not recognising the headers saying it cannot find the include files. I also tried importing the native-audio project into android studio but that too did not compile or run. I am aware that the official support is still not there for using NDK with Android Studio. But I have seen some videos that show how to integrate ndk with android studio.
Is there a way to do it.
Thanks in advance
OpenSL library is available for android platforms with API 9+, so you may want to change the mininimum required sdk.
Not sure how NDK chooses for which platform to compile, but you may need to compile yourself also using a custom Application.mk file like this:
APP_ABI := armeabi
APP_PLATFORM := android-9
TARGET_PLATFORM := android-9
Also, you should always target and compile with the highest available sdk.
Here's an example of what your build file should look like:
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.example.hellojni"
minSdkVersion 9
targetSdkVersion 22
ndk {
moduleName "HelloJNI"
ldLibs "OpenSLES" // Link with these libraries!
stl "stlport_shared"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.1.1'
}
Note: With the above configuration, the libraries are found for me (with the built-in ndk configurations).
I am trying to include some native cpp sources in my android app. I'm using Android Studio 1.0 with the gradle build system. I have three modules: my android app, the android opencv libs, the cpp sources (in the jni folder)
The build process gives me the following error:
D:\NVPACK\android-ndk-r10c\sources\cxx-stl\gnu-libstdc++\4.9\include\bits\stl_pair.h
Error:(96, 12) error: redefinition of 'struct std::pair<_T1, _T2>'
Error:(214, 5) error: redefinition of 'template<class _T1, class _T2> bool std::operator==(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)'
... and some other redefinitions with some other errors in other files.
It seems that the include paths are partially wrong or that there are duplicated headers (stl_pair.h) in the NDK This is my build.gradle file:
apply plugin: 'com.android.library'
android {
compileSdkVersion 21
buildToolsVersion "21.1.1"
defaultConfig {
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
ndk{
moduleName "Native"
cFlags "-I'D:\\OpenCV-2.4.10-android-sdk\\sdk\\native\\jni\\include' " +
"-I'D:\\NVPACK\\android-ndk-r10c\\sources\\cxx-stl\\gnu-libstdc++\\4.9\\include' " +
"-I'D:\\NVPACK\\android-ndk-r10c\\sources\\cxx-stl\\gnu-libstdc++\\4.9\\libs\\armeabi-v7a\\include'"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
}
In cFlags I point to the openCV sources and to the c++ standard sources as described here. This works all fine until the above error.
I have only a very basic understanding of the whole build process when dealing with cpp sources as I normally work with c# .net or android (without native sources).
From my understanding the ndk-build should give me some .so files that I can use in my app. But the build of the natives failes. Am I missing something in the process?
edit: I switched to eclipse and could build and run the code. Maybe I try to switch back to android studio in the future, but this is not so important.