Android - debug native code of AAR library - java

I have the following situation. Due to some requirements I've to extract some parts of our app into a separate AAR library. So it looks like that:
Native C++ code together with some Java wrappers is compiled into an AAR library
The library is then added as a library module in the main app
The compilation itself is configured with Gradle + CMake
Everything works as expected but I've one problem, I cannot debug the native C++ part anymore. Both modules are compiled in DEBUG. It also doesn't help to set the LLDB symbol directory (to LIB_PATH/.externalNativeBuild/cmake/debug/ABI_XXX/CMakeFiles/native-lib.dir/). Setting the LLDB debug type doesn't seem to help either.
When I put my library code back into the main app I can debug everything without a problem.
Is it simply not possible to debug the native part of an AAR library? Or can anyone tell me what I'm doing wrong?

For some reason I found this blog entry only now... http://www.akaita.com/post/android-native-library-module-debug/
Although the author is using the experimental ndk plugin I can confirm that it's also working with the stable gradle version + CMake!

Related

How to implement the SDL2 library into Xamarin.Android?

What I need to do:
Compile the SDL2 source into an .so file for x86 and ARM64 architecture
Reference this file in Xamarin.Android
Call the SDL2 methods in my C# code.
Things I've learned so far:
SDL2 requires a Java Activity or JNI bindings to invoke the native code.
I cannot proceed without somehow integrating SDL2 libs and a JNI to the Xamarin.Android project.
I am incapable of solving this problem and my brain has fried in the process.
Things I've tried:
Outdated GitHub projects:
https://github.com/0x0ade/SDL2Droid-CS
https://github.com/fallahn/sdl2vs
This blog post that lets me create C++ code but not using Xamarin
https://trederia.blogspot.com/2017/03/building-sdl2-for-android-with-visual.html
Running SDL2 through Android Studio which works but doesn't help me as I need to invoke my C# code.
I don't have extensive Xamarin knowledge so I'm not sure how to do this, I can really use another pair of eyes right now. The SDL2Droid-CS GitHub project should theoretically work but I can't find a way to compile the SDL2 used in that project for the x86 emulator included in C#.
I tried compiling my code using armeabiv7 libsdl2.so and then running it directly on my phone. Unfortunately Visual Studio was unable to debug this thus making it difficult for me to implement my code.
Next I tried to debug the previously compiled app (using SDL2Droid-CS) through Android Studio and it gave me this error:
06-19 00:39:55.362 13143-13143/? I/zygote64: Late-enabling -Xcheck:jni
06-19 00:39:55.474 13143-13143/SDL2Droid_CS.SDL2Droid_CS W/ActivityThread: Application SDL2Droid_CS.SDL2Droid_CS can be debugged on port 8100...
06-19 00:39:55.514 13143-13143/? W/monodroid: Creating public update directory: `/data/user/0/SDL2Droid_CS.SDL2Droid_CS/files/.__override__`
Using override path: /data/user/0/SDL2Droid_CS.SDL2Droid_CS/files/.__override__
Using override path: /storage/emulated/0/Android/data/SDL2Droid_CS.SDL2Droid_CS/files/.__override__
Trying to load sgen from: /data/user/0/SDL2Droid_CS.SDL2Droid_CS/files/.__override__/libmonosgen-2.0.so
Trying to load sgen from: /storage/emulated/0/Android/data/SDL2Droid_CS.SDL2Droid_CS/files/.__override__/libmonosgen-2.0.so
Trying to load sgen from: /storage/emulated/0/../legacy/Android/data/SDL2Droid_CS.SDL2Droid_CS/files/.__override__/libmonosgen-2.0.so
Trying to load sgen from: /data/app/SDL2Droid_CS.SDL2Droid_CS-wmPu9Ce48QdJhvYc6bPRiA==/lib/arm64/libmonosgen-2.0.so
Trying to load sgen from: /data/user/0/SDL2Droid_CS.SDL2Droid_CS/files/.__override__/links/libmonosgen-2.0.so
06-19 00:39:55.515 13143-13143/? W/monodroid: Trying to load sgen from: /system/lib/libmonosgen-2.0.so
06-19 00:39:55.515 13143-13143/? A/monodroid: cannot find libmonosgen-2.0.so in override_dir: /data/user/0/SDL2Droid_CS.SDL2Droid_CS/files/.__override__, app_libdir: /data/app/SDL2Droid_CS.SDL2Droid_CS-wmPu9Ce48QdJhvYc6bPRiA==/lib/arm64 nor in previously printed locations.
Do you have a shared runtime build of your app with AndroidManifest.xml android:minSdkVersion < 10 while running on a 64-bit Android 5.0 target? This combination is not supported.
Please either set android:minSdkVersion >= 10 or use a build without the shared runtime (like default Release configuration).
The Min SDK was 19 so the error it gives is weird.
I'm assuming that SDL2 was not implemented properly which is leading to all these problems. The GitHub code has some holes and the person who uploaded it hasn't been active.
Resources:
SDL2 Website: https://www.libsdl.org/
SDL2 Source: https://www.libsdl.org/release/SDL2-2.0.8.zip
SDL2Droid GitHub Project: https://github.com/0x0ade/SDL2Droid-CS
GitHub Project from blog: https://github.com/fallahn/sdl2vs
Blog that explains building SDL2 in Visual Studio
TL;DR: Working files are here: https://github.com/MananAdhvaryu/Android-SDL2-Libraries
So I figured out the crash, it was cause due to the shared runtime that is implemented for debugging by Visual Studio. It was fixed by disabling Shared Runtime in the project settings.
Project Settings -> Android Options -> Untick "Use Shared Runtime"
1. As to why the GitHub Code didn't work:
It was due to broken .jar file in the "bindings" project. I was able to fix it by compiling the .jar file myself from the SDL2 source code. The .java file you need to compile are here, or you can get it from the source code.
Once you have the working .jar simply remove the existing .jar from the Jars folder and replace it with the new one.
If you can't generate the .jar file you can use the one in the GitHub project linked above
2. To create the .so files:
After that the necessary .so file for the processor architecture needs to be compiled. It is done using the Android NDK and a make script. The make script from the SDL2Droid GitHub works fine so I simply changed a few parameters to increase the android minSdkVersion to 19 and got the .so files for all the architectures (x86, x86_64, ARM, ARM64)
#!/bin/bash
NATIVEDIR=$(dirname "$0")
ndk-build -j 4 NDK_PROJECT_PATH="$NATIVEDIR/../SDL2Droid-CS" NDK_APPLICATION_MK="$NATIVEDIR/Application.mk"
This is the bash code to generate the .so files. If you are using Command prompt simply change the "$NATIVEDIR" to the absolute path of your project.
If you cannot generate these native libraries then you can use the one's from the above linked GitHub repository.
they require minimum sdk android-19 and are available for all supported architectures.
To use them simply place the libs folder in your Xamarin.Android project directory.
Call the SDL2 methods in my C# code.
There are official binging for C#. And this is the link on the official website:https://www.libsdl.org/languages.php.
You could download it and compile it to .dll file. Then add it as the reference to your project. You could call the methods by:
using SDL2;
SDL.SDL_SetHint(SDL.SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, "1");

Android Studio - How does a library project used in an app follow with the app-release.apk

I'm using a library (https://github.com/PhilJay/MPAndroidChart) for plotting data in an android app. When app-release.apk is created by the program it is ready to be installed on the tablet I use for testing.
What is puzzling to me is how the parts of the library, which i use, follow with the release. In other scenarios, for example in Visual Studio and c# - program being installed on Window machine, libraries require dll files to be installed and registered on each targeted machine. In my scenario the library is written specifically for Android, but if I somehow managed to include a c++ or a c# library in my Android app using tools like libstdc++ or MONO, would it work the same way when it comes down to app-realease.apk?
Are all classes in a library included in the app-release.apk or just the parts that I use?
Thanks in advance and please let me know if the question is unclear before downvoting it!
Normally, when you build your APK, all the libs you have imported (jars) are included and transformed to dex files, as the rest of your code. So, yes all the classes are included, even if you don't use them.
You can use Proguard to remove them from the APK. Look at this post :
Use Proguard for stripping unused Support lib classes

Android NDK - Excluded Files Still Show Errors

I'm trying to make a cross-platform project using C++ on Windows and the Android NDK. I've been trying to put it together in one project with multiple build configurations, but I'm running into a problem for the Android build.
My project directory structure is as follows:
PROJECT/
src <- This has the Android SDK files
jni <- This has the Android NDK files
src-mp <- Multiplatform C++ code
src-pc <- Windows-specific code
gen
res
...
When building for Android, the src-pc folder contains code that doesn't compile and generates errors (it's using GLFW and GLEW, which doesn't seem to be compatible with Android). I right-clicked on it and hit
"Resource Configurations -> Exclude from Build".
However, the errors in src-pc are still being reported and so Eclipse refuses to run the application. I know the application runs on Android without the src-pc folder.
I suspect it's something with the indexer, but I can't get it to ignore the files in the src-pc folder. I've considered setting up a separate dependent project for Windows, but I was hoping that there was a way to put it all in one project. I've looked at the resource filters functionality, but I don't see a way to set filters for specific build configurations, so that doesn't help.
I already found that it's possible to delete the problem reports in the Problems tab, but doing that every time I build is a nuisance and I was hoping for a better fix.
I'm using Android NDK R9D and the SDK tools for API level 19. I'm on Eclipse Kepler. The toolchain being used for C++ compilation is Cygwin GCC with the Android Builder.

Why am I getting 'undefined symbol' error for class that is on my build path?

I have an eclipse project with a third party library on my build path. I am trying to use a class from this library, which eclipse recognizes (and I can see in the hierarchy of the jar file when I drill down), but when I actually try to build the project I'm getting an 'undefined symbol' error for this type. I am using other libraries on the build path without issue. Any ideas on what might be wrong?
Our projects are built with ANT.
It's hard to answer your question with such a little details.
Here's a few vulnerable points of your build:
Ant is using different version of java compiler than Eclipse does.
Ant is using different version of the library or doesn't use it at all.
Order of your dependencies in your classpath for Ant build is different from one in Eclipse.
More details will get you a better answer.
There are also some existing answered questions to consider. They mainly regarding shared libraries (C++ or else) used in Java applications:
Undefined Symbol Error
Just started C++: Undefined Symbol error on Compile
shared library compiles, but has undefined symbols

Repackaging the .jar file

I need to add some jars from JRE7 library to my Android project. But for example rt.jar is in conflict with android.jar from Adroid 2.2 SDK, so I get this error:
Ill-advised or mistaken usage of a core class (java.* or javax.*)
when not building a core library.
This is often due to inadvertently including a core library file
in your application's project, when using an IDE (such as
Eclipse). If you are sure you're not intentionally defining a
core class, then this is the most likely explanation of what's
going on.
However, you might actually be trying to define a class in a core
namespace, the source of which you may have taken, for example,
from a non-Android virtual machine project. This will most
assuredly not work. At a minimum, it jeopardizes the
compatibility of your app with future versions of the platform.
It is also often of questionable legality.
If you really intend to build a core library -- which is only
appropriate as part of creating a full virtual machine
distribution, as opposed to compiling an application -- then use
the "--core-library" option to suppress this error message.
If you go ahead and use "--core-library" but are in fact
building an application, then be forewarned that your application
will still fail to build or run, at some point. Please be
prepared for angry customers who find, for example, that your
application ceases to function once they upgrade their operating
system. You will be to blame for this problem.
If you are legitimately using some code that happens to be in a
core package, then the easiest safe alternative you have is to
repackage that code. That is, move the classes in question into
your own package namespace. This means that they will never be in
conflict with core system classes. JarJar is a tool that may help
you in this endeavor. If you find that you cannot do this, then
that is an indication that the path you are on will ultimately
lead to pain, suffering, grief, and lamentation.
I know there have been several threads about it and things like JarJar, OneJar or FatJar might be good for me. But I don't know how to make any of them work and documentation doesn't really make it clear (for me). I guess they use Ant commands, but I have always used Eclipse built-in builder and now I have no idea how to use neither Ant nor any of mentioned above.
So my question is: how can I repack this rt.jar so I could compile it in my Android project?
Thank you!
EDIT:
Ok, so what I want to achieve is to create a .jar, which can be used during developing Android application (simplifies some functionalities, doesn't really matter). But I would also like to be able to add the very same .jar to standard Java project in order to use some functions there as well. It would look like this:
Whoever writes an application adds this .jar to his Java project -> it enables him to generate certain files (internet is needed to do it) -> these generated files are then added to Android project -> later on, when somebody uses this Android app, these files provide certain functionalities without using internet (off-line).
It would be ill-advised to do this in any project at all, even if it were possible. You would be opening yourself to a wealth of class incompatibility and loading problems. But in any case it doesn't even matter because the core Java libraries are loaded way before your archives are even touched, making any such attempt at overriding them moot.
Not to even talk about the fact that Android is using its own JVM implementation which is not fully compatible with JDK 6 (forget JDK 7). Also note that it may be a copyright violation to package the core Java libraries with your code and could change your licensing options (IANAL).
You need to find another way to resolve whatever issue you are having (which you failed to mention in your question).
There are many JARs that work nicely on both Android and on classic Java. None involve having Android developers pirate rt.jar. Stick to java.* and javax.* classes that exist in both the Android SDK and in whatever level of Java you are supporting, and your JAR will work fine in both environments.
You should ideally refrain from using such .jar files, but if you must, you can add them to build path. But this, at times results in a conflict, like the one that you are facing right now. What you need to do to resolve this kind of a conflict, is:
add the jar in the build path.
Check "referenced libraries". The jar file should appear under the same.
once it features under referenced libraries, check the "android dependencies" virtual directory. If you get to see that you have an instance of the same jar file there as well, you should delete the "android dependencies" folder altogether. (Trust me, this does not affect your project in any way).
having done that, you should be able to compile your code without any further conflicts.
Happy coding.. :)

Categories

Resources