Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Existing .so file in android application [closed]

I was searching for library which should convert .doc/.docx to .pdf in android platform.

I got PdFTron android sdk,in that they have given libPDFNetC.so file.

For Conversion, there is class called Convert, inside that there is a method toPDF(), in that method they have internally called native method FileToPdf().I tried that code but unable to call that native method and was getting errors

I want to know that if there is existing .so file present with you and if you want to call native method which is present in .so file then is there need to use JNI?. i dont know much about JNI. any help.

like image 721
AndroUser Avatar asked Jan 18 '13 10:01

AndroUser


2 Answers

You have to link your final shared library that is generated by the Android NDK using the ndk-build to the PDF shared library you said you already have compiled for the ARM architecture. (Ensure that this is the case, otherwise the library won't work on Android!)

For that, if for example you have the following directory structure:

jni
└── libs
└────── my_shared_lib.so
└── Android.mk
└── Application.mk

You need to have the following content inside the Android.mk file:

LOCAL_PATH := $(call my-dir)

# define our prebuilt shared library as a module to the build system
include $(CLEAR_VARS)
LOCAL_MODULE := mysharedlib
LOCAL_SRC_FILES := libs/my_shared_lib.so
include $(PREBUILT_SHARED_LIBRARY)

# The final shared library that will be bundled inside the .apk
include $(CLEAR_VARS)
LOCAL_MODULE := mynativelib
LOCAL_LDLIBS := -landroid -llog
LOCAL_CPPFLAGS := -O0 -g3 -std=c++11 -Wall -Wextra 
LOCAL_SHARED_LIBRARIES := mysharedlib
LOCAL_C_INCLUDES := myheader1.h myheader2.h
LOCAL_SRC_FILES := src_file1.cpp src_file2.cpp
include $(BUILD_SHARED_LIBRARY)

and the contents of the Application.mk file (for using the C++ Standard Library, and build the the final shared library for two different versions of the ARM architecture):

APP_OPTIM := debug
APP_PLATFORM := android-14
APP_STL := gnustl_static
APP_ABI := armeabi armeabi-v7a

Then after you compile your code from within Eclipse or from the command line using the ndk-build script it'll compile you final shared library and link it against your prebuilt shared library (i.e. the PDF shared library you said you are trying to use).

For shared libraries the apk that is generated and deployed to the device/emulator contains the final shared library as well as all the prebuilt shared libraries you linked against, in contrast with linking against static libraries which are not bundled inside the apk.

For your use case you should have two shared libraries in the lib directory of your Android application after the apk is unpacked on the device. You can check this by running the following command from a terminal:

adb shell ls -l /data/data/com.company.myapp/lib

Replace com.company.myapp with your application's package name.

Also, don't forget to put the following inside a static context of a Java class:

class MyClass
{
      static
      {
            try
            {
                System.loadLibrary("mynativelib");
            }
            catch (UnsatisfiedLinkError ule)
            {
               Log.e(TAG, "WARNING: Could not load native library: " 
                      + ule.getMessage());
            }
      }

       // other code here...
}

Notice the use of the same name inside the System.loadLibrary method call as the final shared library name.

like image 93
Alex Bitek Avatar answered Nov 11 '22 23:11

Alex Bitek


You need to make sure the .so file that maps to the native interface is available on your system, and can be found by Java.

There should be a call like System.loadLibrary("<libraryname>") or System.load("/path/to/libs/lib<libraryname>.so") somewhere in your Java code. That will instruct the JVM to search for the library with the given name and load it.

  • System.load("/path/to/libs/lib<libraryname>.so") will just look for the file specified as argument, and load it.
  • System.loadLibrary("<libraryname.") will look in the configured library path for a library with the name lib<libraryname>.so . The library path is taken from the system variable java.library.path .

Also make sure that the library version you are loading is compatible with the Java JNI mapping!

like image 38
Dieter Van de Walle Avatar answered Nov 12 '22 00:11

Dieter Van de Walle