I am working on a project using Android and native code through JNI.
Android Studio editor keeps telling me that it cannot resolve the native method yet it compiles an executes my program fine.
// In the Java file
private native void startROSNode();
// In the C++ file
JNIEXPORT void JNICALL Java_com_laas_lumusapp_ROSThread_startROSNode(JNIEnv* env, jobject obj)
Is there something I am missing ? (even if it is not project critical it bugs me to see that red line in my editor :))
Thank you in advance !
There might be several reasons, most likely this is due to the ndk 'experimental plugin' (Assuming you have not migrated to CMake). Take a look here, perhaps this will help you: Android Studio 2.0's inline compiler does no longer recognize native code
Related
I have an Android native library (C++ code base) called:
libserverapp.so
And I cannot get the Android build to find it:
"DllNotFoundException: serverapp"
I am using an internal build system, but when I parse the output of the build process, I can see many calls of the form:
android-ndk/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/arm-linux-androideabi-g++.exe -march=armv7-a
After building my Android app, I inspect the resulting APK (renaming to .zip and extracting), and can see my library file here:
lib/armeabi-v7a/libserverapp.so
I can confirm that "ARMv7" is the target architecture in the Android Player settings, and I access the library, in C#, via:
[DllImport("serverapp", CallingConvention = CallingConvention.Cdecl)]
private static extern void run_sim(StringBuilder matchInput, StringBuilder results, int randomSeed);
I have built a Windows DLL of the C++ code, to use in the Editor, and everything works great. However, when I move to Android, the .so cannot be found. The import settings for libserverapp.so are:
Platform: Android; CPU: ARMv7; Path: Assets/Plugins/Android/libserverapp.so; Type: Native
Given that the final APK includes the .so where I expect it to be (lib/armeabi-v7a/), I assume my Unity settings are correct? Also, I am not using IL2CPP for the Android build.
Finally, when I do an object dump of the library file (using arm-linux-androideabi-objdump.exe), the file format of the library file is "elf32-littlearm".
I feel that the issue here is simply finding the .so, not the functionality within it. Any ideas on what's going on here?
Thanks!
I ended up solving the problem. I mentioned that was using an internal build system. Well, there seems to be a bug in it. I ported things over to official Android NDK makefiles, and then it "just worked". So in this case, the library could be found, but its contents weren't valid.
I have an NDK shared library and I want to do some tests against it. I currently used googletest to create an native executable that links to the library, followed instructions in the README.NDK. A dummy executable can run on a Android emulator. Good.
Now, the tricky thing is that the shared library calls a lot of functions of an JNIEnv instance, for example:
env->NewStringUTF()
...
The question is, how can an Android native executable get an instance of JNIEnv?
One method is to use the invocation API described below.
http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html
However, I looked at the jni.h of NDK, and it seems disallow the usages of this API:
/*
* VM initialization functions.
*
* Note these are the only symbols exported for JNI by the VM.
*/
#if 0 /* In practice, these are not exported by the NDK so don't declare them */
jint JNI_GetDefaultJavaVMInitArgs(void*);
jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*);
jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*);
#endif
Any suggestions are highly appreciated!
(I am new to Android so please correct me if I am wrong. Thanks!)
This is done via AttachCurrentThread().
It is benign to call this if the thread is already attached.
I am building an Android App with native support. The app compiles and runs when I'm using a Mac. Now I want to switch to a Windows for development, I get this error when I try to run the app. I'm probably just missing the obvious here, any ideas?
Error:Execution failed for task ':app:compileMyApp_moduleArm64-v8aDebugSharedLibraryMyApp_moduleMainC'.
No tool chain is available to build for platform 'arm64-v8a':
- Tool chain 'ndk-gcc' (GNU GCC): Could not find C compiler 'aarch64-linux-android-gcc'. Searched in:
- C:\AndroidDevelopment\android-ndk-r10e\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin
- C:\AndroidDevelopment\android-ndk-r10e\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin
- C:\AndroidDevelopment\android-ndk-r10e\toolchains\aarch64-linux-android-4.9\prebuilt\windows-x86_64\bin
- C:\AndroidDevelopment\android-ndk-r10e\toolchains\x86-4.9\prebuilt\windows-x86_64\bin
- C:\AndroidDevelopment\android-ndk-r10e\toolchains\x86_64-4.9\prebuilt\windows-x86_64\bin
- C:\AndroidDevelopment\android-ndk-r10e\toolchains\mipsel-linux-android-4.9\prebuilt\windows-x86_64\bin
- C:\AndroidDevelopment\android-ndk-r10e\toolchains\mips64el-linux-android-4.9\prebuilt\windows-x86_64\bin
The .c file related to the error:
#include <jni.h>
JNIEXPORT jstring JNICALL
Java_co_mhmt_myapp_ui_activities_MainActivity_nativeFun(JNIEnv *env, jclass type) {
return (*env)->NewStringUTF(env, "Hello from the other side");
}
It happens with NDK installations, especially on Windows. In most cases, simple reinstall (preferably - automatic via Android Studio upgrade) solves the problem. Note that the new release 11 has been released recently.
The problem was, as others stated, related to the NDK installation. Possibly because I had downloaded and extracted the NDK manually. Doing so through Android Studio solved the problem.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I load my own Java class in C on Android?
Application works in debug / run from Eclipse, but .APK gives .classNotFoundException when parsing XML layout that contains a custom View
In Android, I am accessing a native C library, by doing:
System.loadLibrary("testlib");
To load a native library.
In the JNI_OnLoad() function, it is trying to find a Java glue code class:
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env;
jclass k;
jint r;
r = vm->GetEnv ((void **) &env, JNI_VERSION_1_4);
k = env->FindClass ("com/test/android/aclass");
The FindClass() fails, and throws a NoClassDefFoundError exception.
Any idea why I cannot see my Java class from my C code?
I use this same library in another test application, and it works (so I am confident that the library works). I don't see why one app can find the java class, while the other cannot.
Found the answer.
My clue was that it would run fine if I ran it through eclipse, and only had this problem when I created a .apk file.
I found the solution here: Application works in debug / run from Eclipse, but .APK gives .classNotFoundException when parsing XML layout that contains a custom View
I have built FFMPEG executables and libraries as provided by Bambuser (http://bambuser.com/opensource). So I managed to build the Android executables and libraties. How can I link these libs in my Eclipse project and invoke the FFmpeg functions from Java? The open source code includes the C header-files.
I am new to native coding for Android, and I could not find an easy answer for this. In basic : having a bunch of Android compatible libraries and some C header files what do I have to do to reuse those libaries' functionality from java (+Android SDK)?
Any help would be appreciated.
Kind regards,
WhyHow
You have to write some C glue code using the JNI conventions to expose the FFmpeg functionalities to Java code. Here's an example of a JNI method implemented in C from the Android NDK samples:
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz )
{
return (*env)->NewStringUTF(env, "Hello from JNI !");
}
You also need some Java code to load the library and declare the native method.
public class HelloJni
{
public native String stringFromJNI();
static {
System.loadLibrary("hello-jni");
}
}
I found this project on sourceforge which already has implemented some JNI interface to ffmpeg to integrate it with the Java Media Framework. You may find it useful.
There's another Java FFI technology called JNA (Java Native Access) that allows you to declare native function prototypes in Java and call them directly. Using it may require less boilerplate code. See this project for an Android implementation. (I have never used it myself)