Thanks to visit codestin.com
Credit goes to github.com

Skip to content
/ nano Public

πŸ”₯πŸ”₯πŸ”₯ Android SO file compression framework designed to reduce the size of shared object (SO) files within APK or AAB files

License

threeloe/nano

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

12 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Nano

License PRs Welcome Release

README δΈ­ζ–‡η‰ˆ

Nano is an Android SO file compression framework designed to reduce the size of shared object (SO) files within APK or AAB files while supporting runtime dynamic loading. Common use cases include:

  • Pre-installed apps - Device manufacturers often require SO files to be stored in non-compressed form within the APK, significantly increasing package size while imposing strict size limitations.
  • Lite versions - Applications with extremely stringent package size requirements.

Demo Screenshot

Demo screenshot

Quick Start

Plugin Integration

Declare plugin dependencies and repositories in your root build.gradle:

buildscript {
    repositories {
        maven { url "https://jitpack.io" }
    }

    allprojects {
        repositories {
            maven { url "https://jitpack.io" }
        }
    }

    dependencies {
        classpath "com.github.threeloe.nano:plugin:1.0.2"
    }
}

Apply the Nano plugin in your app's build.gradle:

apply plugin: "com.threeloe.nano"
nano {
    enable = true
    compressMethod = "zstd" // Compression method, supports zstd and xz
    groups {  // Group configuration, each group can be compressed into multiple file blocks
        launch {
            blockNum 4  
            include "libijkffmpeg.so"
            include "libijkplayer.so"
            include "libijksdl.so"
            include "libshadowhook.so"
        }
        second {
            blockNum 2
            include "libtensorflowlite_jni.so"
            include "libtensorflowlite_gpu_jni.so"
        }
    }
}

SDK Integration

Add the sdk dependency:

dependencies {
    implementation "com.github.threeloe.nano:nano:1.0.2"
    //zstd decompression method for Android
    implementation "com.github.luben:zstd-jni:1.5.7-3@aar"
}

For Android 9+ Only (e.g., pre-installed apps)

If you only want to support Android 9 and above, such as in pre-installed package , you can simply register the AppComponentFactory:

@RequiresApi(Build.VERSION_CODES.P)
class DemoAppComponentFactory : AppComponentFactory(){
    override fun instantiateClassLoader(cl: ClassLoader, aInfo: ApplicationInfo): ClassLoader {
        // Replace with the new ClassLoader
        return Nano.install(cl, aInfo)
    }
}

And initialize code in the Application:

class DemoApplication :Application() {

    override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(base)
        val nanoConfig = NanoConfig()
        // configure the decompression method implementation
        nanoConfig.zstdCompressMethod(object : IDecompressMethod {
            override fun getDecompressedStream(input: InputStream): InputStream {
                return ZstdInputStream(input)
            }
        })
        Nano.init(application, nanoConfig)

        //Business logic starts here
    }

    override fun onCreate() {
        super.onCreate()
        MMKV.initialize(
            this
        )
        //Business logic
    }
}

For Full Android Compatibility (5.0+)

If you want to support all Android versions, you need to modify the application's Application to inherit from NanoApplication and migrate the original business initialization logic to a NanoApplicationLike implementation class, as shown below:

class DemoApplication : NanoApplication() {

    override fun getApplicationLikeClassName(): String {
        return "com.threeloe.nano.demo.app.DemoApplicationLike"
    } 
}

class DemoApplicationLike(app: Application) : NanoApplicationLike(app) {

    override fun attachBaseContext(base: Context?) {
        super.attachBaseContext(base)
        val nanoConfig = NanoConfig()
        // configure the decompression method implementation
        nanoConfig.zstdCompressMethod(object : IDecompressMethod {
            override fun getDecompressedStream(input: InputStream): InputStream {
                return ZstdInputStream(input)
            }
        })
        Nano.init(application, nanoConfig)
        //Business logic starts here
    }

    override fun onCreate() {
        super.onCreate()
        //Business logic 
        MMKV.initialize(
            application
        )
    }
}

Features

  • Group Compression - Support SO file grouping, each group can be split into multiple blocks for concurrent decompression.
  • Decompression Modes - Supports synchronous/asynchronous decompression.
interface NanoApi {

    fun init(application: Application, config: NanoConfig?)

    //synchronous decompression, will block the current thread until decompression is complete
    fun decompress(group: String): NanoResult

    //asynchronous decompression,  callback will be invoked when decompression is complete
    fun decompressAsync(group: String, callback: (NanoResult) -> Unit)

}
  • Compression Algorithms - zstd (faster decompression) or xz (higher compression ratio). Nano Plugin supports both zstd and xz compression methods, with zstd being the default. Only choose one decompression method implementation at runtime for better APK size. You can configure it as follows: For zstd:
dependencies {
    /**
     * You can use other zstd decompression libraries
    */ 
    implementation "com.github.luben:zstd-jni:1.5.7-3@aar"
}
val nanoConfig = NanoConfig()
nanoConfig.zstdCompressMethod(object : IDecompressMethod {
    override fun getDecompressedStream(input: InputStream): InputStream {
        return ZstdInputStream(input)
    }
})

For xz:

dependencies {
    /**
     * You can use other xz decompression libraries
     */
    implementation "org.tukaani:xz:1.9"
}
val nanoConfig = NanoConfig()
nanoConfig.xzCompressMethod(object : IDecompressMethod {
    override fun getDecompressedStream(input: InputStream): InputStream {
        return XZInputStream(input)
    }
})

Compatibility

  • Gradle Plugin: Compatible with Android Gradle Plugin 7.0 and above
  • Android Versions: Supports Android 5.0 (API 21) and higher

License

Apache License

About

πŸ”₯πŸ”₯πŸ”₯ Android SO file compression framework designed to reduce the size of shared object (SO) files within APK or AAB files

Resources

License

Stars

Watchers

Forks

Packages

No packages published