Is there a way to use JNI calls directly in the Qt application? I've read how to use NDK itself (creating jni folder, Android.mk, compiling "by hands"). Does Qt give you opportunity to avoid this actions? Or it only uses NDK to work with Qt libraries?
If I understood your question correctly, then this is something that even the Qt Project internally has to use for certain functionality that is not available by the native platform, just through the Darvik layer, so this means a "yes" to your question.
Also, you may wish to look into the Qt Android Extras module to have a convenient Qt wrapper around that functionality to enable the smoother integration.
Qt Android Extras C++ Classes
For your convenience, here goes the gist inline:
QAndroidJniEnvironment Access to the JNI Environment
QAndroidJniObject Provides APIs to call Java code from C++
Related
I am a native Android developer, and a client has asked me to re-use his Qt library project in a native Android app. I am really new to Qt development, I mean, I understand C/C++ but have never dealt with Qt development itself, neither the environment or the deployment methods.
I have been looking into these solutions, but I don't get any closer to being able to create an Android project with a Qt library inside with which I can interact.
Similar solutions:
http://thebugfreeblog.blogspot.com/2012/05/embedded-cross-platform-development-for.html
https://developer.android.com/studio/projects/add-native-code#create-sources
My question: How do I export my Qt project to a usable format for my Android project? Any step-by-step guide would be really appreciated.
Thanks!
Assuming your Qt application is only used for its logic (not the GUI side), what you need it to:
Adding JNI to your Qt library for Android
JNI (Java Native Interface) allows creating an interface to link and use native (C++) code from Java. This is used to wrap your C++ code and provide functions visible and usable directly from your Android application
Install the version of Qt you want for Android using Qt's online installer (a checkbox when choosing the version of Qt you want)
Create a JNI interface to allow your application and the library to talk. This is covered in that sample: https://developer.android.com/ndk/samples/sample_hellojni. I would probably recommend creating another C++/JNI library acting as a wrapper for your C++/Qt library. That way you don't contaminate the original library with JNI dependencies.
Integrate your JNI library in your application
Once your have a JNI interface, you have to cross-compile and ship that library with your Android application
Build your native library from Android Studio (after pointing to your Qt libraries and include dir). Alternatively, you can manually build it from Qt Creator (slightly easier) and import only the resulting .so. But that will be painful if your Qt library changes
Package the library (.so), and load it when your application starts. This is also covered in the sample. Once the library is loaded, you will be able to use the JNI functions that you exposed and pass arguments, after some conversion work. Your Android application can also pass a handle to the native library, allowing communication in both ways.
Notes
Be careful to the licensing of your project. Cross-compiling Qt for Android will likely switch to its GPLv3 or Commercial license, versus LGPLv3 without Android.
Qt libraries have to be included in your final pacakge. So they either have to be statically linked against your original library, or dynamically linked, and stored in your APK
You can leverage Qt JNI classes to make the creation of the interface easier, but that is not required: https://doc.qt.io/qt-5/qandroidjniobject.html
Threading can become difficult, as calls to/from JNI have to run from the main thread
I would recommend starting from a working example if you find one, as that whole setup will definitely take some time. I don't know of a complete tutorial covering that, but feel free to share if you find one!
I built a library(.so) that is being called from JNI code in some android app. The JNI code is built using NDK.
If I build the library using android tool-chain, the library works well when called from JNI code.
If I build the library using another tool-chain (used on the same ARM device for none android applications), the library crashes when called from JNI code.
why do we need to use android tool-chain (or NDK) for compiling c/c++ code running in the context of an android app? why not use other tool-chains?
You can use other toolchains, but it requires special care.
Maybe a good starter would be to learn the UBERTC and Linaro Wiki.
The main difference is that NDK compilers are tuned for bionic (Android variant of C runtime libraries). Originally, bionic was a modest subset of Linux runtime. On latest platforms, most of the gap is closed, but now there are many extensions that you probably need.
Also, Android dynamic linker may require (depending on target platform) a set of ELF flags that are automatically delivered by NDK binutils, like PIC, id, and others.
It is quite possible to use arm-linux toolchain to build a statically linked executable that will run on Android, but for a library that must play well on the JNI environment the effort is probably not worth it.
Note that NDK provides tools to create a standalone toolchain, which behaves very similar to other toolchains you may be familiar with. This approach makes it easy to adopt 3rd-party libraries with sophisticated build scripts.
I am using LibGDX to write apps for both Android and iOS and I want to be able to add C++ code to my apps to optimize certain parts and to port some functions etc.
I have been searching the internet and tried to follow some tutorials, but did not find what I need.
How can I write a very basic C++ library which I can load in LibGDX? Which tools do I need to use? Visual Studio? I develop in Android Studio.
I think that I need an .so file for Android and an .a file for iOS, is that correct?
On both platforms, it's possible to include a precompiled library as well as C++ source code directly.
On Android, you'll want to look into using the Android NDK. This allows you to include native C/C++ code that can bridge over to Java. The connection between Java and C/C++ is managed with the JNI. It's a fairly tedious, awkward system for communicating between C++ and Java. You'll want to look into setting up an Android.mk makefile that specifies how to include your library (or source code) into your build.
On iOS, it's a little more tightly linked. You can have Objective-C++ files that can run both C++ and Objective-C code. If you're using Swift, it's a little different (bridging between Objective-C++ and Swift).
In some cases, when the platform (Android/iOS) provides functionality that is superior to what is possible or realistic with C++, you might find yourself architecting the code such that your C++ can reach out to the platform as needed. This means that you might have headers with separate implementation files per platform.
thing.h
thing_android.cpp
thing_ios.mm
The android app's Android.mk file will include thing_android.cpp (but not thing_ios.mm). This file could cross the JNI bridge to talk to Java as needed, whenever you need something from Android SDK.
The iOS app will include thing_ios.mm (but not thing_android.cpp). The .mm extension signifies Objective-C++, so that file could directly call powerful Cocoa libraries as needed.
Finally, on all platforms, you'll want to be sure to either scale back your usage of C++ to the lowest common denominator platform. In other words, if iOS supports a particular feature of C++, and Android doesn't, then you cannot use that particular feature.
Qt (http://qt-project.org/) looks like a great cross-platform framework for developing applications, however I can't seem to find if it can be use to create libraries.
Can I use it to create a reusable piece of code that will be compiled to a Windows .dll, OSX and iOS .dylib and Android .jar file?
Usually, the only difference between an application and a shared library is a few option bits in the image file. So yes, you can certainly use Qt to write reusable software libraries.
Here are the caveats:
If the libraries that you create expose C++ interfaces (as opposed to C interfaces), your users will need to use the same compiler version to build their code that links with your library. The C interfaces must be declared extern C.
If the library that you use is linking dynamically against Qt, then your user is forced to use a binary-compatible version of Qt: that means that it must be compiled with the same compiler, and without binary-incompatible changes.
For use on non-package-managed platforms (like Windows), I'd link my library statically to both Qt and the Visual C++ runtime. For platforms with package managers (Linux, macports on OS X), I'd offer both a statically linked library as well as a platform-specific package (say RPMs for RHEL6, macports portfile, etc.) that then depends on platform-standard C++ runtime, and Qt if such exists (some platforms don't provide Qt 5 yet).
I want to use C++ file in my android application via JNI but i don't know how to integrate C++ file and how to Compile and run it.
Please help me if anybody knows about it
You need to do NDK programming. Android NDK
The Android NDK is a toolset that lets you embed components that make use of native code in your Android applications.
Android applications run in the Dalvik virtual machine. The NDK allows you to implement parts of your applications using native-code languages such as C and C++. This can provide benefits to certain classes of applications, in the form of reuse of existing code and in some cases increased speed.
You can use Android NDK for your requirements.
Android-NDK
The NDK is a toolset that allows you to implement parts of your app using native-code languages such as C and C++. For certain types of apps, this can be helpful so that you may reuse existing code libraries written in these languages and possibly increased performance.
Tutorial Advanced Android: Getting Started with the NDK
Using Android NDK create shared library of your C,C++ files and load that library at runtime from your Android application. Look at tutorial I linked.