How to include .so files in Android studio Library Module? - android-studio

I've been trying to include .so files in a library module using android studio, but unable to to do so and getting java.lang.UnsatisfiedLinkError.
I've also unzipped and checked the apk generated from App Module (which depends upon my library module containing .so files), it does contains all the required .so files in it, but still i get the java.lang.UnsatisfiedLinkError
I've also tried all the other solutions present on existing threads like converting .so files to jar and then adding as dependency, adding .so files to jniLibs folder, converting library module to jar and adding jar dependency to app-module etc but no result?
p.s I'm using android studio 2.0 with gradle plugin version 2.0

You can try the following project structure. It worked for me with nothing the gradle.
> project/
libs/
fm.jar, etc. // <-- .jar files go here
src/
main/
java/
(your java files)
jniLibs/
arm64-v8a/
libopus.so, etc. // <-- .so files for ARM 64-bit go here
armeabi-v7a/
libopus.so, etc. // <-- .so files for ARM 32-bit go here
x86/
libopus.so, etc. // <-- .so files for Intel 32-bit go here
res/
(your drawables/layouts/values)

Related

How to make Android Studio aware of source code directory for prefab-published .AAR libraries?

Using Android Studio Electric Eel, AGP 7.5, NDK r23 and prefab. In my local Maven repository, I have a precompiled .AAR with some prefab-published static libraries. I.e. the .AAR contains both .a and .h files.
In my native app (using NDK-build, not CMake), I add the debug-compiled version of my library:
dependencies {
implementation 'org.foo:mylib-debug:1.0'`
}
When debugging the app, I can indeed step through the native code, but not always:
Setting breakpoints and stepping into methods of...
The native app itself, works! E.g. app/main.cpp
Inline mylib methods in the .h files (packaged in the .AAR), works!
Non-inlined mylib methods in .c files opened in Android Studio, works!
Non-inlined mylib methods in .c files not opened in Android Studio, does not work!
It is apparent that Android Studio is not aware of the source directory for my native source code. Manually opening a source file indeed makes it aware of that particular file. So the question is:
How do you specify a known source directory for debugging a pre-compiled static library?
Ideally, I would want the mylib library project to specify this path, so that consumers don't need to remember adding some folder location (unless the path changed). This library is mainly to be used locally, so the source folder will rarely change.
What I tried so far
In tried specifying a folder in app/build.gradle, but it didn't help:
sourceSets {
main {
jni.srcDirs = ["${System.env.MYLIB_SOURCES}/src"]
}
}
I also tried setting some idea specific directory:
idea {
module {
sourceDirs += file("${System.env.MYLIB_SOURCES}/src")
}
}
Also tried adding the source directory under Debug Configuration -> Symbol Directories, but that didn't help.
In Visual Studio this whole thing would be trivial; just try stepping into a method and it will ask you for the source location if it can't find it. How hard can it be?

How do I safely change the "lib" directory name in Flutter Android Studio project?

I've created a Flutter app in Android Studio and I want to change the name of the "lib" directory (in which Dart source files reside) to "src".
However when I do that, the import to 'package:/main.dart' fails. How can I change that?
I changed the path in the .iml file, and the project compiles and runs, but this test file still shows an error.
This name is hardcoded and there is no way to change it.
The whole pub package system depends on that directory name.
There is also a convention that tools like the analyzer support code in lib/src being considered package-private when not exported by files in other directories in lib/.

Android-NDK: Unsatisfied Link Error : Cannot load library: soinfo_relocate: cannot locate symbol "tcgetattr"

I am building the app available at https://github.com/thibautd/android-serialport-api/tree/master/android-serialport-api/project using Android NDK.
What have I done until now:
Build the project using gradle version 'com.android.tools.build:gradle-experimental:0.7.0-alpha1'
I am building this on android-17 and running on Android device with 4.2. I have also tried android-19
Build goes through without any errors but at runtime I get the exception Cannot load library: soinfo_relocate: cannot locate symbol "tcgetattr"
I have tried several options to get this working but all of them fail
Options I have tried
Setting APP-PLATFORM like mentioned in Cannot locate symbol 'tcgetattr' referenced by "libcrypto.so"
Using $(PREBUILT_SHARED_LIBRARY) by including the .so file avialable in the same github location as mentioned in How can i Link prebuilt shared Library to Android NDK project?
Tried setting LOCAL_EXPORT_C_INCLUDES in both option 1) and 2) above as mentioned in the same post How can i Link prebuilt shared Library to Android NDK project?
Also tried option mentioned at Cannot load library: reloc_library[1285]: cannot locate 'rand'
Put all the required include files directly in the project under /jni and tried building the project.
My project compiles absolutely fine. When testing I have always deleted the contents in build folder and rebuilt the project. To make sure the .so files are indeed created properly.
In all the cases I end up in exactly the same error soinfo_relocate: cannot locate symbol "tcgetattr"
I think it is because of the fact that some of the includes like unistd.h are not correctly referenced in runtime but I am not able to figure out how to get this working.

copy static files to build output folder in gradle

I was using ANT before (Android Project) and i had "static" files in the same packages as my code
Here is an example
src/com/my/app/test/Parser.java
src/com/my/app/test/json_to_parse.json
When executing the unit tests, the json file was copied into the gen folder, therfor it was possible to access the json in the test with
getClass().getResourceAsStream(fileName)
I had to convert the project to gradle, but now the tests are failing.
After checking the "build" folder, i've realised, the .json files are not there, therefor the getResourceAsStream method returns null.
Any idea how to include these "static" files (json, xml, ...) into the build folder?
Moving the files into the resources folder did not work out of the box in Android Studio (even though is should have)
This should be fixed in Android Studio 1.2.
However, this is what i did:
Moved all static files into the resources folder.
In my unit-test module i've added this to the build.gradle file
task copyTestResources(type: Copy) {
from "${projectDir}/src/test/resources"
into "${buildDir}/classes/test"
}
processTestResources.dependsOn copyTestResources
Now, all files located inside src/test/resources will be copied into /classes/test where i can access them with
getClass().getResourceAsStream(fileName)
If i keep the package structure inside the resources folder the same as it was in the java folder, i don't need to adjust any code.
To complete the story a bit more:
JUnit4 runner requires
getClass().getResourceAsStream(name)
while Robolectric requires
getClass().getClassLoader().getResourceAsStream(name)
The files you are asking about are called "resource files" in Maven/Gradle lingo.
Gradle assumes that you are using the Maven Standard Directory Layout.
So, either you move your files into src/test/resources (then Gradle will pick them up automatically), or you tell Gradle that it should look for resources in some other place.
In the latter case, you need to modify the processTestResources task. However, keeping resource files in the same directory as source code is a bad practice. So I advise the former option.
if your problem is happen when you create apk with AndroidStudio.
you can create a jar file that includes your resources with jar.exe
for example i put a.txt into resources directory
and run this code in cmd:
"C:\Program Files\Java\jdk1.7.0_79\bin\jar" cvfe res.jar -c resources
after that a jar file "res.jar" was created
then add that res.jar into libs folder in your project
when your apk is creating resources are added to your final apk and you can use this code to acsess a.txt:
someclass.class.getClassLoader().getResourceAsStream("resources/a.txt");
with this job no need to change Gradle setting.

Update module created from local aar

Here is my setup : I have an android library that creates an aar when exported and I have an android app that uses the library as a module (it's the only way to import a local aar file).
To import the aar file as a module in my android app, I click on File -> New Module... -> Import .JAR or .AAR Package and I choose my exported aar file. After that I only need to add a compile project line in my gradle file to be able to use my library.
I update very often my library because I am currently developing it and I want to test it frequently. The problem is that I don't know how to update the module in my android app project...
What I am doing now is that I issue a gradlew assembleRelease in my android library project to create the new aar file, then in my android app project I delete the module in the Module Settings (or Project Structure) window, I delete the module folder at the root of my project and then I import it again. This whole operation takes around 3 minutes each time I want to test my library and I am tired of this. Do you know if there is a faster way of updating an android module created from an aar file?
I thought that importing a aar file as a module was the only solution to include a local aar file, but it seems that it can be done easily by simulating a repository with a flat directory.
In your project gradle file in the allprojects.repositories tag, add the following :
flatDir {
dirs 'libs'
}
In your app module, make sure you have a libs folder with the aar file in it. Then add the compile line in the dependencies tag of your app module gradle file.
dependencies {
compile 'package:name:version#aar'
}
Now, when you update the aar file in your libs directory, your app will use the updated version of your library.
Note:
In compile 'package:name:version#aar', name is physical file name
of the library. For example lib-debug or lib-release etc.
version and package can be found in AndroidManifest.xml inside
.aar file. (How to open .aar file?)

Resources