create a nativescript plugin for Android with compiled C files - android

I'm trying to create a nativescript plugin, following the official documentation here
I created my .aar file and copied it into the platforms/android folder, which is working when I call my plugin class. The problem I'm facing is when I try to call a function that loads a native library, giving me a UnsatisfiedLinkError.
I've already seen these links 1 2 and tried all the options mentioned, but none of them seems to work. Since those links are two years old, I wonder if these methods are now deprecated.
My tns version is 4.1.2 and tns-android is 4.1.3.
I've tried adding the *.so files to the following folders:
platforms/android
platforms/android/libs
platforms/android/libs/armeabi
platforms/android/libs/jni
platforms/android/libs/jni/armeabi
platforms/android/armeabi
platforms/android/jni
platforms/android/jni/armeabi
platforms/android/jniLibs
platforms/android/jniLibs/armeabi
As you can see, I've tried all possible combinations based on the previous posts (my *.so files are for armeabi architecture)
Note that the only case that don't fail as the others is platforms/android/jniLibs/armeabi. While trying this one I got an error telling me that one of the .so files is repeated (merge conflict) when calling tns debug android, the other ones just fail on runtime when I call the function

I believe linker error is totally from your native library. Your call from plugin to native Java class is successful here, Java to C seems to be the issue.
Did you verify whether your native library (.so files) were compiled successfully, may be by importing them in a simple Android app? If it still fails, then it has nothing do with {N} runtime but may be something with NDK compilation.

Related

Android Studio External Native Build Precompiled Headers

I'm porting a project from NDK build to Android Studio.
Currently the project has a precompiled header attached (with NDK build), which speeds up compilation time a lot.
I'm looking for a way to add precompiled header (.pch) to my external native build within Android Studio project. I'm using CMake.
I am in the same situation and I have found several user-made script to do that.
I would recommend this one:
https://github.com/larsch/cmake-precompiled-header
In order to make it work for the latest ndk-tools which uses clang, copy paste the content of this pull request:
https://gist.github.com/leeor/316168500765cf51ae97
into the PrecompiledHeader.cmake file (replace everything in this file, except if you want to keep GCC/ MSVC compatibility, then just you will have to merge the two files which shouldn't be hard).
It should work, except some special CMAKE_CXX_FLAGS that triggers an error in the export_all_flags function, and that I don't know how to fix yet. I'll keep you updated with my progress.

DllNotFoundException on Android

I'm trying to load shared libraries in Unity. It works on Windows/Editor but not on Android, whatever I do or use for libraries I always get the DllNotFoundException.
I am using lib.so files, those are for 32BIT ARM EABIS, so the cross platform compilation seems to succeed.
my lib.so files are in the Assets/Plugins/Android/libs/armeabis-v7a/ folder.
I tried different syntax for DllImport (assuming the lib is called Plugin, and the files Plugin.dll and libPlugin.so) :
[DllImport("Plugin")] => works for Windows only
[DllImport("libPlugin.so")] => obviously wont work for Windows, but doesn't work for Android either.
If I open the .apk with winrar, libs are in the libs/armeabis-v7a folder.
The smartphone I use for my tests is an OnPlus3 with a armv8 processor.
Anyone managed to sucessfuly load a shared native library on Android ? Any ideas about what I'm doing wrong ?
Thank you
EDIT:
plugin code can be found here : https://github.com/FFmpeg/FFmpeg
C# code can be found here : https://github.com/Ruslan-B/FFmpeg.AutoGen/blob/7e001dde3acaad70ed188b75e686f23574f81388/FFmpeg.AutoGen/FFmpegInvoke.cs
Adding FFmpegInvoke.cs in the Unity Project or generating the FFmpeg.Autogen.dll and adding it to the project gives the same result (dll just makes the Unity Project faster to build).
I noticed few things you are doing wrong:
my lib.so files are in the Asset/Plugins/libs/armeabis-v7a/ folder.
That should be at:
Assets/Plugins/Android/libs/armeabi-v7a
If you have the x86 architecture version of the plugin,you should place them at:
Assets/Plugins/Android/libs/x86
I tried different syntax for DllImport (assuming the lib is called
Plugin, and the files Plugin.dll and libPlugin.so) :
None of those are correct. If the plugin file name is "libPlugin.so", you should use "Plugin" as the name.
Do not include the lib prefix.
Do not include the ".so" postfix.
Again, if the plugin name is "libVideoPlayer.so", you have to use "VideoPlayer". The "lib" and ".so" are removed. Nothing else will work.
One final note for you, for Android C++ plugin, you do not need to export the plugin. For example, DLLExport __declspec(dllexport) is not necessary.
Although, you must put the function name inside "extern "C""

Proper way to create android project with c++ support

I'm running the latest build of android studio. Trying to make a project compilable and running utilizing the power of this https://github.com/tpruvot/cpuminer-multi/ c++ stuff. What I've tried so far is create new project with c++ support - it creates the corresponding project structure. It also includes CPP file that is called from the main activity. Now let's say I want all this aforementioned miner code to be there as well - I’ve tried just copy-pasting it into the cpp folder. What are my next steps? Calling ndk-build against $ProjectFileDir$\app\src\main directory just fails with an error Android NDK: Your APP_BUILD_SCRIPT points to an unknown file: ./jni/Android.mk . Same goes if I try to import an existing project like https://github.com/mdelling/cpuminer-android - first of all I’m trying to do and ndk-build, but it just fails saying that it treats warning like errors so all the cpp/h functions remain inaccessible and are not packed into resulting apk. If I try to install the resulting apk it just crashed on the start. So for the first case – how can I like all the cpp sources to the app, and for the second – how can I make it work at all?
First of all, the crash is probably because your Java code is trying to load the c++ shared library and fails, because the library was not built due to the NDK errors. So take care of the errors first.
Second, did you configure your Android.mk properly? Have a look here, for example (it is for Eclipse and not Android Studio, but the mk file is the same): Getting started with Android NDK. Looking at an existing simple project can also help: hello-jni.

Creating and using Java Bindings library for PocketSphinxAndroidDemo

I want to create a Java Bindings library for the PocketSphinx Android Demo project for Xamarin, that I can then use in my Android application. I have done the following:
downloaded the PocketSphinxAndroidDemo project, and installed and run it on my Android device using Eclipse without any issues - the native java code works nicely.
created a Java Bindings library in Visual Studio with the pocketsphinx-android-0.8-nolib.jar file marked as an EmbeddedJar and marked Copy to output directory always and got this to compile fine. I'm using the jar from the downloaded demo project.
added an android application project to my Visual Studio solution and added a reference to my bindings library.
added lib/armeabi/libpocketsphinx_jni.so to my application project (also armeabi-v7a) (using the files from the demo project) and marked the *.so files as AndroidNativeLibrary with Copy to Output directory set to Copy Always.
No matter what I do I can't run the line of C# code
var config = Decoder.DefaultConfig();
I always get a Java.Lang.UnsatisfiedLinkError exception (as described in my forum post here). I'm trying to run this line of code because the demo project has this line of java:
Config config = defaultConfig();
My question is, do I need to use DllImport here? Or perhaps Java.Lang.JavaSystem.LoadLibrary? Is this a scenario where the project should be built using ndk-build?
I have tried both DllImport and LoadLibrary with no success. Any leads or things to try much appreciated!
Thanks in advance,
David
Following on from a response that I got in this forum thread, I worked out that I needed to call
Java.Lang.JavaSystem.LoadLibrary("pocketsphinx_jni");
in the OnCreate method of my class, before calling the DefaultConfig method.

Sharing Java library with Android Apps

I'm just getting started in Android development, and use Netbeans with NBAndroid and SDK 17.
I'd like to use the same Java source code in my Java and Android app.
http://developer.android.com/guide/developing/projects/projects-eclipse.html says how to do it in Eclipse (although it is sketchy on the .JAR connection thing), but I can't seem to make it work in NB.
Based on that link, My understanding is that the correct setup for the Android app is an Android Application project which references an Android Library project which in turn references a .JAR library produced by a Java Library project. I could then also have a Java Application project referring to the same Java Library project.
So, I've set up this project structure... I have an AndroidApp project which is a basic HelloAndroid Activity in a com.ex package. This project includes an AndroidLib library project in the Libraries folder. I also have a LibClass.java file which defines a simple LibClass class which has one function getText() that just returns a String to be displayed. The MainActivity in the AndroidApp calls this to get the String to output.
When I put LibClass.java directly into the AndroidLib project, everything is fine.
But what I want to do is to share the source code with Java.
So I want to move the LibClass.java into the JavaLib library, whose .JAR file is included in the AndroidLib project. However, when I tried that, I get an error in the MainActivity class, complaining it can't find LibClass. Looking at the Projects window, I can see LibClass.class inside the com.ex package in the JavaLib.jar in the Libraries folder of the AndroidLib project. And AndroidLib is visible in the Libraries folder of the AndroidApp project, but it doesn't show any packages or other contents there.
So I feel like I'm just one step away from making this work. Do I need to do something with one or other of the AndroidManifest files perhaps? Or do something with the build.xml files? Or am I on the wrong track altogether?
I'd be really grateful if someone could post a how-to for this.
I'm trying something similar; I've got Java EE projects, built using Eclipse, and I'm trying to utilize some of that code from my Android projects. This should give me a shared codebase rather than a bunch of confusing SVN externals which I've had to endure before.
Rather than creating JAR files I've found that working with the source and building for the platform works best (well, it has been working but I've got a problem with it at the moment). So, what I'm doing is:
c:\MySvnFolderStructure\MyJavaProjectFolder\src\ (and then all the source under that)
c:\MySvnFolderStructure\MyJavaProjectFolder\android\ (and all the Eclipse Android project gubbins)
c:\MySvnFolderStructure\MyJavaProjectFolder\jee\ (and all the Eclipse JEE project gubbins)
The Android and Java EE projects do not have their own src folders, they both link to the src folder in their parent folder. What this means is that each of the Java implementations is building its own byte code version from the source, and using its own external libraries (like the Apache HTTP ones, for example).
Naturally they can't share stuff like awt (as mentioned in another post), but there's plenty of stuff that does cross-over especially if it's core Java classes that are being used.
Also, it's proving a bit tricky writing JUnit tests as there needs to be some duplication of the test code at the moment because the Android ones need extra instrumentation, but I'm working on it.
Also, see this post about relative paths in Eclipse, which means the folders can be checked-out to different places on different machines (like we all do with our version control check-outs) and still be shared.
if I understand your situation correct, you are trying to use a custom java library for both your android and java applications.
For this scenario, you can build the java library first. Instead of adding the java library jar as android library, you can drop the jar directly inside the libs folder of android project and add it to android project's build path.
If you are using ANT scripts for building the java library jar , you can consider adding the source files also as part of jar. This will help you get code assistance when you develop the android part. But this part is purely optional.
The problem is that the Java platform in Android is different from the JDK platform.
In particular, the .JAR library CANNOT refer to anything that is not icluded in the Android platform. An example of things you can't refer to is java.awt.* (except you can have java.awt.fonts).
There is also a difference between JDK String and Android String -- Android does not implement the isEmpty() method.

Categories

Resources