Class SoLoader
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 in the source code by default but disabled for the OSS package via meta-data config. The application could define com.facebook.soloader.enabled metadata entry to override the default behavior.
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 enable SoLoader:
<application ...>
<meta-data
tools:replace="android:value"
android:name="com.facebook.soloader.enabled"
android:value="true" />
</application>
-
Nested Class Summary
Nested Classes -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringName of the directory we use for extracted DSOs from built-in SO sources (main APK, exopackage)static final intAllow deferring some initialization work to asynchronous background threads.static final intIn some contexts, using a backup so source in case of so corruption is not feasible e.g.static final intExperiment ONLY: disable the fsync job in soSourcestatic final intDeprecated.static final intExperiment ONLY: skip DSONotFound error recovery for back up so sourcestatic final intExperiment ONLY: skip custom SoSources for base.apk and rely on System.loadLibrary calls.static final intDeprecated.static final intEnable the exopackage SoSource.static final intExperiment ONLY: use theSystemLoadWrapperSoSourceto instead of the directApk/Application soSource.static final intFor compatibility, we need explicitly enable the backup soSource.static final intstatic final intstatic final intSkip calling JNI_OnLoad if the library is merged.static final Stringstatic final String -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic booleanThis function ensure that every SoSources Abi is supported for at least one abi in SysUtil.getSupportedAbisstatic SoSource[]static voidMake shared-library loading delegate to the system.static String[]getLibraryDependencies(String libName) Gets the dependencies of a library.static StringgetLibraryPath(String libName) Gets the full path of a library.static intReturns count of already loaded so librariesstatic FileReturns the so file for the specified library.static intstatic 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) 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 voidinit(android.content.Context context, ExternalSoMapping externalSoMapping) 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 booleanstatic booleanloadLibrary(String shortName) static booleanloadLibrary(String shortName, int loadFlags) Load a shared library, initializing any JNI binding it contains.static StringRetrieve an LD_LIBRARY_PATH value suitable for using the native linker to resolve our shared libraries.static voidprependSoSource(SoSource extraSoSource) Add a new source of native libraries.static voidTurn shared-library loading into a no-op.static voidProvide a wrapper object for callingSystem.loadLibrary(java.lang.String).static FileunpackLibraryAndDependencies(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 Details
-
TAG
- See Also:
-
VERSION
- See Also:
-
SO_STORE_NAME_MAIN
Name of the directory we use for extracted DSOs from built-in SO sources (main APK, exopackage)- See Also:
-
SOLOADER_ENABLE_EXOPACKAGE
public static final int SOLOADER_ENABLE_EXOPACKAGEEnable the exopackage SoSource.- See Also:
-
SOLOADER_ALLOW_ASYNC_INIT
public static final int SOLOADER_ALLOW_ASYNC_INITAllow deferring some initialization work to asynchronous background threads. Shared libraries are nevertheless ready to load as soon as init returns.- See Also:
-
SOLOADER_LOOK_IN_ZIP
public static final int SOLOADER_LOOK_IN_ZIP- See Also:
-
SOLOADER_DISABLE_BACKUP_SOSOURCE
public static final int SOLOADER_DISABLE_BACKUP_SOSOURCEIn 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:
-
SOLOADER_SKIP_MERGED_JNI_ONLOAD
public static final int SOLOADER_SKIP_MERGED_JNI_ONLOADSkip 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:
-
SOLOADER_DONT_TREAT_AS_SYSTEMAPP
Deprecated.Deprecated, NO EFFECT- See Also:
-
SOLOADER_ENABLE_DIRECT_SOSOURCE
Deprecated.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:
-
SOLOADER_EXPLICITLY_ENABLE_BACKUP_SOSOURCE
public static final int SOLOADER_EXPLICITLY_ENABLE_BACKUP_SOSOURCEFor 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:
-
SOLOADER_DISABLE_FS_SYNC_JOB
public static final int SOLOADER_DISABLE_FS_SYNC_JOBExperiment ONLY: disable the fsync job in soSource- See Also:
-
SOLOADER_ENABLE_SYSTEMLOAD_WRAPPER_SOSOURCE
public static final int SOLOADER_ENABLE_SYSTEMLOAD_WRAPPER_SOSOURCEExperiment ONLY: use theSystemLoadWrapperSoSourceto instead of the directApk/Application soSource. This could work on the apps w/o superpack or any other so file compression.- See Also:
-
SOLOADER_ENABLE_BASE_APK_SPLIT_SOURCE
public static final int SOLOADER_ENABLE_BASE_APK_SPLIT_SOURCEExperiment ONLY: skip custom SoSources for base.apk and rely on System.loadLibrary calls.- See Also:
-
SOLOADER_ENABLE_BACKUP_SOSOURCE_DSONOTFOUND_ERROR_RECOVERY
public static final int SOLOADER_ENABLE_BACKUP_SOSOURCE_DSONOTFOUND_ERROR_RECOVERYExperiment ONLY: skip DSONotFound error recovery for back up so source- See Also:
-
SOLOADER_IMPLICIT_DEPENDENCIES_TEST
public static final int SOLOADER_IMPLICIT_DEPENDENCIES_TEST- See Also:
-
-
Constructor Details
-
SoLoader
public SoLoader()
-
-
Method Details
-
init
- Throws:
IOException
-
init
public static void init(android.content.Context context, int flags, @Nullable SoFileLoader soFileLoader) throws IOException Initializes 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 loader- Throws:
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:
-
init
public static void init(android.content.Context context, @Nullable ExternalSoMapping externalSoMapping) throws IOException Initializes 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.This is used only by apps that use SoMerging in OSS, such as React Native apps.
- Parameters:
context- application contextexternalSoMapping- the customExternalSoMappingif the App is using SoMerging.- Throws:
IOException- IOException
-
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
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
Gets 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:
IOException- if there is an error calculating the canonical path of libName
-
cloneSoSources
-
getLibraryDependencies
Gets 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:
IOException- if there is an error reading libName
-
getSoFile
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
-
loadLibrary
Load 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:
UnsatisfiedLinkError
-
unpackLibraryAndDependencies
Unpack 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:
UnsatisfiedLinkError
-
isInitialized
public static boolean isInitialized() -
getSoSourcesVersion
public static int getSoSourcesVersion() -
prependSoSource
Add a new source of native libraries. SoLoader consults the new source before any currently-installed source.- Parameters:
extraSoSource- The SoSource to install- Throws:
IOException- IOException
-
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
-