3

I'm currently working on a project which will use a prebuilt shared library. But I'm quite confused on the process of importing a prebuilt library, as well as calling the methods in the prebuilt from the new project java class.

Let's say:

  1. Project A has generated the libA.so files for each ABI_ARCH.

  2. I'm trying to use them in my Project B.

What is the proper way to import them, and how to call the methods of libA.so which are declared in A. In another word how to use the exposed APIs of libA.so ?

Hang Alec
  • 103
  • 2
  • 11

1 Answers1

4

These days Google has pre-released a new feature that will allow easy reuse of prebuilt native libraries. If you are not ready yet to jump to Android Studio 4.0, and/or to build the necessary AAR for libA, you can use the old ways.

There are three different tracks, depending on what the nature of your Project B is.

  1. If it only loads libA.so from Java/Kotlin, it's enough to specify jniLibs.src in build.gradle: How can I add .so files to an android library project using gradle 0.7+. Note that all classes that have native methods which are implemented in libA.so must be copied to Project B keeping their fully qualified names intact.

  2. If the second project uses ndk-build, you should include $(PREBUILT_SHARED_LIBRARY). An NDK guide has further up-to-date details.

  3. If the project uses CMake, you use add_library(… SHARED IMPORTED). An Android Srudio documentation explains different scenarios.

It's important to emphasise a tiny difference between ndk-build and CMake in their treatment of prebuilt .so libraries. While ndk-build will copy these libraries to the installation directory with all libraries that it builds, CMake does not provide this assistance. Therefore, you will probably add the folder that holds the prebuilt library to jniLibs.src in build.ghradle (as in the case 1 above).

In all 3 scenarios, make sure that the libraries that you get packed into your APK or AAB are stripped of debug symbols.

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • Thanks for your answer, I tried using the 1st approach by copying the *.so file to /main/jniLibs/ and added jnilibs.src on build.gradle, also using System.loadLibrary("A") to load the jniLib. When I tried run the app, it crash with an error said "didn't find class A" – Hang Alec Feb 24 '20 at 04:20
  • In addition, the above error occurs when the *.so files are compiled from c++; When the *.so files are complied from .c the error was "No implementation found for long A.method(long)..." – Hang Alec Feb 24 '20 at 05:26
  • It turns out to be the mismatch of package name, the new project has to have an identical package and class to use the *.so files. – Hang Alec Feb 24 '20 at 09:29
  • 2
    @HangAlec: you don't need to change the package name for the whole project. Only the classes that have native methods which are implemented in **libA.so**, must be copied to **Project B** keeping their *fully qualified names* intact. – Alex Cohn Feb 24 '20 at 15:54