Class SoLoader

java.lang.Object
com.facebook.soloader.SoLoader

@ThreadSafe public class SoLoader extends Object
Native 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 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>
 
  • Field Details

    • TAG

      public static final String TAG
      See Also:
    • VERSION

      public static final String VERSION
      See Also:
    • SO_STORE_NAME_MAIN

      public static final String 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_EXOPACKAGE
      Enable the exopackage SoSource.
      See Also:
    • 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:
    • 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_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:
    • 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:
    • SOLOADER_DONT_TREAT_AS_SYSTEMAPP

      @Deprecated public static final int SOLOADER_DONT_TREAT_AS_SYSTEMAPP
      Deprecated.
      Deprecated, NO EFFECT
      See Also:
    • SOLOADER_ENABLE_DIRECT_SOSOURCE

      @Deprecated public static final int 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_SOSOURCE
      For compatibility, we need explicitly enable the backup soSource. This flag conflicts with SOLOADER_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_JOB
      Experiment ONLY: disable the fsync job in soSource
      See Also:
    • SOLOADER_ENABLE_SYSTEMLOAD_WRAPPER_SOSOURCE

      public static final int SOLOADER_ENABLE_SYSTEMLOAD_WRAPPER_SOSOURCE
      Experiment ONLY: use the SystemLoadWrapperSoSource to 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_SOURCE
      Experiment 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_RECOVERY
      Experiment 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

      public static void init(android.content.Context context, int flags) throws IOException
      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 this init(android.content.Context, int) is called. This method is idempotent: calls after the first are ignored.
      Parameters:
      context - application context
      flags - Zero or more of the SOLOADER_* flags
      soFileLoader - the custom SoFileLoader, 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 context
      nativeExopackage - pass SOLOADER_ENABLE_EXOPACKAGE as 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 this init(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 context
      externalSoMapping - the custom ExternalSoMapping if 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

      public static void setSystemLoadLibraryWrapper(SystemLoadLibraryWrapper wrapper)
      Provide a wrapper object for calling System.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 String getLibraryPath(String libName) throws IOException
      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

      public static SoSource[] cloneSoSources()
    • getLibraryDependencies

      @Nullable public static String[] getLibraryDependencies(String libName) throws IOException
      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

      @Nullable public static File getSoFile(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(String shortName)
    • loadLibrary

      public static boolean loadLibrary(String shortName, int loadFlags) throws UnsatisfiedLinkError
      Load a shared library, initializing any JNI binding it contains.
      Parameters:
      shortName - Name of library to find, without "lib" prefix or ".so" suffix
      loadFlags - Control flags for the loading behavior. See available flags under SoSource (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

      public static File unpackLibraryAndDependencies(String shortName) throws UnsatisfiedLinkError
      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

      public static void prependSoSource(SoSource extraSoSource) throws 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:
      IOException - IOException
    • makeLdLibraryPath

      public static 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 APK
      async - - 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