Package com.facebook.soloader
Class SoLoader
- java.lang.Object
-
- com.facebook.soloader.SoLoader
-
@ThreadSafe public class SoLoader extends java.lang.ObjectNative code loader.To load a native library, call the static method
loadLibrary(java.lang.String)from the static initializer of the Java class declaring the native methods. The argument should be the library's short name.Note: SoLoader is enabled by default. Application could define com.facebook.soloader.enabled metadata entry to control using SoLoader or System Loader.
For example, if the native code is in libmy_jni_methods.so:
class MyClass { static { SoLoader.loadLibrary("my_jni_methods"); } }Before any library can be loaded SoLoader needs to be initialized. The application using SoLoader should do that by calling SoLoader.init early on app initialization path. The call must happen before any class using SoLoader in its static initializer is loaded.
An example of the meta data entry to disable SoLoader:
<application ...> <meta-data android:name="com.facebook.soloader.enabled" android:value="false" /> </application>
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classSoLoader.WrongAbiError
-
Field Summary
Fields Modifier and Type Field Description static intSOLOADER_ALLOW_ASYNC_INITAllow deferring some initialization work to asynchronous background threads.static intSOLOADER_DISABLE_BACKUP_SOSOURCEIn some contexts, using a backup so source in case of so corruption is not feasible e.g.static intSOLOADER_DISABLE_FS_SYNC_JOBExperiment ONLY: disable the fsync job in soSourcestatic intSOLOADER_DONT_TREAT_AS_SYSTEMAPPSystem Apps ignore PREFER_ANDROID_LIBS_DIRECTORY.static intSOLOADER_ENABLE_DIRECT_SOSOURCEIn API level 23 and above, it’s possible to open a .so file directly from your APK.static intSOLOADER_ENABLE_EXOPACKAGEEnable the exopackage SoSource.static intSOLOADER_EXPLICITLY_ENABLE_BACKUP_SOSOURCEFor compatibility, we need explicitly enable the backup soSource.static intSOLOADER_LOOK_IN_ZIPstatic intSOLOADER_SKIP_MERGED_JNI_ONLOADSkip calling JNI_OnLoad if the library is merged.static java.lang.StringVERSION
-
Constructor Summary
Constructors Constructor Description SoLoader()
-
Method Summary
Modifier and Type Method Description static booleanareSoSourcesAbisSupported()This function ensure that every SoSources Abi is supported for at least one abi in SysUtil.getSupportedAbisstatic voiddeinitForTest()Make shared-library loading delegate to the system.static java.lang.String[]getLibraryDependencies(java.lang.String libName)Gets the dependencies of a library.static java.lang.StringgetLibraryPath(java.lang.String libName)Gets the full path of a library.static intgetLoadedLibrariesCount()Returns count of already loaded so librariesstatic java.io.FilegetSoFile(java.lang.String shortName)Returns the so file for the specified library.static intgetSoSourcesVersion()static voidinit(android.content.Context context, boolean nativeExopackage)Backward compatibility.static voidinit(android.content.Context context, int flags)static voidinit(android.content.Context context, int flags, SoFileLoader soFileLoader)static voidinit(android.content.Context context, int flags, SoFileLoader soFileLoader, java.lang.String[] denyList)Initializes native code loading for this app; this class's other static facilities cannot be used until thisinit(android.content.Context, int)is called.static booleanisInitialized()static booleanloadLibrary(java.lang.String shortName)static booleanloadLibrary(java.lang.String shortName, int loadFlags)Load a shared library, initializing any JNI binding it contains.static java.lang.StringmakeLdLibraryPath()Retrieve an LD_LIBRARY_PATH value suitable for using the native linker to resolve our shared libraries.static java.lang.StringmakeNonZipPath(java.lang.String localLdLibraryPath)static voidprependSoSource(SoSource extraSoSource)Add a new source of native libraries.static voidsetInTestMode()Turn shared-library loading into a no-op.static voidsetSystemLoadLibraryWrapper(SystemLoadLibraryWrapper wrapper)Provide a wrapper object for callingSystem.loadLibrary(java.lang.String).static java.io.FileunpackLibraryAndDependencies(java.lang.String shortName)Unpack library and its dependencies, returning the location of the unpacked library file.static booleanuseDepsFile(android.content.Context context, boolean async, boolean extractToDisk)Enables the use of a deps file to fetch the native library dependencies to avoid reading them from the ELF files.
-
-
-
Field Detail
-
VERSION
public static java.lang.String VERSION
-
SOLOADER_ENABLE_EXOPACKAGE
public static final int SOLOADER_ENABLE_EXOPACKAGE
Enable the exopackage SoSource.- See Also:
- Constant Field Values
-
SOLOADER_ALLOW_ASYNC_INIT
public static final int SOLOADER_ALLOW_ASYNC_INIT
Allow deferring some initialization work to asynchronous background threads. Shared libraries are nevertheless ready to load as soon as init returns.- See Also:
- Constant Field Values
-
SOLOADER_LOOK_IN_ZIP
public static final int SOLOADER_LOOK_IN_ZIP
- See Also:
- Constant Field Values
-
SOLOADER_DISABLE_BACKUP_SOSOURCE
public static final int SOLOADER_DISABLE_BACKUP_SOSOURCE
In some contexts, using a backup so source in case of so corruption is not feasible e.g. lack of write permissions to the library path.- See Also:
- Constant Field Values
-
SOLOADER_SKIP_MERGED_JNI_ONLOAD
public static final int SOLOADER_SKIP_MERGED_JNI_ONLOAD
Skip calling JNI_OnLoad if the library is merged. This is necessary for libraries that don't define JNI_OnLoad and are only loaded for their side effects (like static constructors registering callbacks). DO NOT use this to allow implicit JNI registration (by naming your methods Java_com_facebook_whatever) because that is buggy on Android.- See Also:
- Constant Field Values
-
SOLOADER_DONT_TREAT_AS_SYSTEMAPP
public static final int SOLOADER_DONT_TREAT_AS_SYSTEMAPP
System Apps ignore PREFER_ANDROID_LIBS_DIRECTORY. Don't do that for this app.- See Also:
- Constant Field Values
-
SOLOADER_ENABLE_DIRECT_SOSOURCE
public static final int SOLOADER_ENABLE_DIRECT_SOSOURCE
In API level 23 and above, it’s possible to open a .so file directly from your APK. Enabling this flag will explicitly add the direct SoSource in soSource list.- See Also:
- Constant Field Values
-
SOLOADER_EXPLICITLY_ENABLE_BACKUP_SOSOURCE
public static final int SOLOADER_EXPLICITLY_ENABLE_BACKUP_SOSOURCE
For compatibility, we need explicitly enable the backup soSource. This flag conflicts withSOLOADER_DISABLE_BACKUP_SOSOURCE, you should only set one of them or none.- See Also:
- Constant Field Values
-
SOLOADER_DISABLE_FS_SYNC_JOB
public static final int SOLOADER_DISABLE_FS_SYNC_JOB
Experiment ONLY: disable the fsync job in soSource- See Also:
- Constant Field Values
-
-
Method Detail
-
init
public static void init(android.content.Context context, int flags) throws java.io.IOException- Throws:
java.io.IOException
-
init
public static void init(android.content.Context context, int flags, @Nullable SoFileLoader soFileLoader) throws java.io.IOException- Throws:
java.io.IOException
-
init
public static void init(android.content.Context context, int flags, @Nullable SoFileLoader soFileLoader, java.lang.String[] denyList) throws java.io.IOExceptionInitializes native code loading for this app; this class's other static facilities cannot be used until thisinit(android.content.Context, int)is called. This method is idempotent: calls after the first are ignored.- Parameters:
context- application contextflags- Zero or more of the SOLOADER_* flagssoFileLoader- the customSoFileLoader, you can implement your own loaderdenyList- Skip load libs from system soSource, due to the linker namespace restriction- Throws:
java.io.IOException- IOException
-
init
public static void init(android.content.Context context, boolean nativeExopackage)Backward compatibility.- Parameters:
context- application contextnativeExopackage- passSOLOADER_ENABLE_EXOPACKAGEas flags if true- See Also:
- What is exopackage?
-
setInTestMode
public static void setInTestMode()
Turn shared-library loading into a no-op. Useful in special circumstances.
-
deinitForTest
public static void deinitForTest()
Make shared-library loading delegate to the system. Useful for tests.
-
setSystemLoadLibraryWrapper
public static void setSystemLoadLibraryWrapper(SystemLoadLibraryWrapper wrapper)
Provide a wrapper object for callingSystem.loadLibrary(java.lang.String). This is useful for controlling which ClassLoader libraries are loaded into.- Parameters:
wrapper- the wrapper you wanna set
-
getLibraryPath
@Nullable public static java.lang.String getLibraryPath(java.lang.String libName) throws java.io.IOExceptionGets the full path of a library.- Parameters:
libName- the library file name, including the prefix and extension.- Returns:
- the full path of the library, or null if it is not found in none of the SoSources.
- Throws:
java.io.IOException- if there is an error calculating the canonical path of libName
-
getLibraryDependencies
@Nullable public static java.lang.String[] getLibraryDependencies(java.lang.String libName) throws java.io.IOExceptionGets the dependencies of a library.- Parameters:
libName- the library file name, including the prefix and extension.- Returns:
- An array naming the dependencies of the library, or null if it is not found in any SoSources
- Throws:
java.io.IOException- if there is an error reading libName
-
getSoFile
@Nullable public static java.io.File getSoFile(java.lang.String shortName)
Returns the so file for the specified library. Returns null if the library does not exist or if it's not backed by a file.- Parameters:
shortName- Name of library to find, without "lib" prefix or ".so" suffix- Returns:
- the File object of the so file
-
loadLibrary
public static boolean loadLibrary(java.lang.String shortName)
-
loadLibrary
public static boolean loadLibrary(java.lang.String shortName, int loadFlags) throws java.lang.UnsatisfiedLinkErrorLoad a shared library, initializing any JNI binding it contains.- Parameters:
shortName- Name of library to find, without "lib" prefix or ".so" suffixloadFlags- Control flags for the loading behavior. See available flags underSoSource(LOAD_FLAG_XXX).- Returns:
- Whether the library was loaded as a result of this call (true), or was already loaded through a previous call to SoLoader (false).
- Throws:
java.lang.UnsatisfiedLinkError
-
unpackLibraryAndDependencies
public static java.io.File unpackLibraryAndDependencies(java.lang.String shortName) throws java.lang.UnsatisfiedLinkErrorUnpack library and its dependencies, returning the location of the unpacked library file. All non-system dependencies of the given library will either be on LD_LIBRARY_PATH or will be in the same directory as the returned File.- Parameters:
shortName- Name of library to find, without "lib" prefix or ".so" suffix- Returns:
- Unpacked DSO location
- Throws:
java.lang.UnsatisfiedLinkError
-
makeNonZipPath
@Nullable public static java.lang.String makeNonZipPath(java.lang.String localLdLibraryPath)
-
isInitialized
public static boolean isInitialized()
-
getSoSourcesVersion
public static int getSoSourcesVersion()
-
prependSoSource
public static void prependSoSource(SoSource extraSoSource) throws java.io.IOException
Add a new source of native libraries. SoLoader consults the new source before any currently-installed source.- Parameters:
extraSoSource- The SoSource to install- Throws:
java.io.IOException- IOException
-
makeLdLibraryPath
public static java.lang.String makeLdLibraryPath()
Retrieve an LD_LIBRARY_PATH value suitable for using the native linker to resolve our shared libraries.- Returns:
- the LD_LIBRARY_PATH in string
-
areSoSourcesAbisSupported
public static boolean areSoSourcesAbisSupported()
This function ensure that every SoSources Abi is supported for at least one abi in SysUtil.getSupportedAbis- Returns:
- true if all SoSources have their Abis supported
-
useDepsFile
public static boolean useDepsFile(android.content.Context context, boolean async, boolean extractToDisk)Enables the use of a deps file to fetch the native library dependencies to avoid reading them from the ELF files. The file is expected to be in the APK in assets/native_deps.txt. Returns true on success, false on failure. On failure, dependencies will be read from ELF files instead of the deps file.- Parameters:
context- - Application context, used to find native deps file in APKasync- - If true, initialization will occur in a background thread and we library loading will wait for initialization to complete.extractToDisk- - If true, the native deps file will be extract from the APK and written to disk. This can be useful when the file is compressed in the APK, since we can prevent decompressing the file every time.- Returns:
- True if initialization succeeded, false otherwise. Always returns true if async is true.
-
getLoadedLibrariesCount
public static int getLoadedLibrariesCount()
Returns count of already loaded so libraries- Returns:
- number of loaded libraries
-
-