feat: use extractNativeLibs to reduce installed app size
While this increases the APK size, it also reduces the installed size due to libs not having to be extracted.
This commit is contained in:
parent
ac33d65bcf
commit
3bbd1bebed
3 changed files with 40 additions and 8 deletions
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
<application
|
||||
android:name=".ManagerApplication"
|
||||
android:extractNativeLibs="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:largeHeap="true"
|
||||
|
|
|
|||
|
|
@ -6,14 +6,13 @@ import com.aliucord.manager.manager.PathManager
|
|||
import com.aliucord.manager.patcher.StepRunner
|
||||
import com.aliucord.manager.patcher.steps.StepGroup
|
||||
import com.aliucord.manager.patcher.steps.base.Step
|
||||
import com.aliucord.manager.patcher.steps.base.StepState
|
||||
import com.aliucord.manager.patcher.steps.download.CopyDependenciesStep
|
||||
import com.github.diamondminer88.zip.*
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
/**
|
||||
* Align certain files in the APK to the respective boundaries.
|
||||
* Align certain files in the APK to the necessary boundaries.
|
||||
*/
|
||||
class AlignmentStep : Step(), KoinComponent {
|
||||
private val paths: PathManager by inject()
|
||||
|
|
@ -24,12 +23,8 @@ class AlignmentStep : Step(), KoinComponent {
|
|||
override suspend fun execute(container: StepRunner) {
|
||||
val apk = container.getStep<CopyDependenciesStep>().patchedApk
|
||||
|
||||
if (Build.VERSION.SDK_INT < 29) {
|
||||
state = StepState.Skipped
|
||||
return
|
||||
}
|
||||
|
||||
var resourcesArscBytes: ByteArray? = null
|
||||
var nativeLibPaths: List<String>? = null
|
||||
var dexCount: Int = -1
|
||||
|
||||
// Align resources.arsc due to targeting API 30 for silent install
|
||||
|
|
@ -54,6 +49,18 @@ class AlignmentStep : Step(), KoinComponent {
|
|||
}
|
||||
}
|
||||
|
||||
// Align native libs due to using extractNativeLibs
|
||||
nativeLibPaths = ZipReader(apk).use { zip ->
|
||||
val libPaths = zip.entryNames.filter { it.endsWith(".so") }
|
||||
for ((idx, path) in libPaths.withIndex()) {
|
||||
// Index is just used as a placeholder id to cache on disk
|
||||
val bytes = zip.openEntry(path)!!.read()
|
||||
val file = paths.patchingWorkingDir().resolve("$idx.so")
|
||||
file.writeBytes(bytes)
|
||||
}
|
||||
libPaths
|
||||
}
|
||||
|
||||
ZipWriter(apk, /* append = */ true).use { zip ->
|
||||
// Delete all the unaligned files from APK
|
||||
if (resourcesArscBytes != null)
|
||||
|
|
@ -62,6 +69,9 @@ class AlignmentStep : Step(), KoinComponent {
|
|||
for (i in 0..<dexCount)
|
||||
zip.deleteEntry(getDexName(i))
|
||||
|
||||
for (path in nativeLibPaths)
|
||||
zip.deleteEntry(path)
|
||||
|
||||
// Write all the files back aligned this time
|
||||
if (resourcesArscBytes != null)
|
||||
zip.writeEntry("resources.arsc", resourcesArscBytes, ZipCompression.NONE, 4)
|
||||
|
|
@ -71,6 +81,13 @@ class AlignmentStep : Step(), KoinComponent {
|
|||
val bytes = file.readBytes()
|
||||
zip.writeEntry(getDexName(idx), bytes, ZipCompression.NONE, 4)
|
||||
}
|
||||
|
||||
// Write back native libraries aligned to 16KiB page boundary
|
||||
for ((idx, path) in nativeLibPaths.withIndex()) {
|
||||
val file = paths.patchingWorkingDir().resolve("$idx.so")
|
||||
val bytes = file.readBytes()
|
||||
zip.writeEntry(path, bytes, ZipCompression.NONE, 16384)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ object ManifestPatcher {
|
|||
private const val DEBUGGABLE = "debuggable"
|
||||
private const val VM_SAFE_MODE = "vmSafeMode"
|
||||
private const val USE_EMBEDDED_DEX = "useEmbeddedDex"
|
||||
private const val EXTRACT_NATIVE_LIBS = "extractNativeLibs"
|
||||
private const val REQUEST_LEGACY_EXTERNAL_STORAGE = "requestLegacyExternalStorage"
|
||||
private const val NETWORK_SECURITY_CONFIG = "networkSecurityConfig"
|
||||
private const val LABEL = "label"
|
||||
|
|
@ -91,19 +92,24 @@ object ManifestPatcher {
|
|||
mapOf(
|
||||
LABEL to appName,
|
||||
DEBUGGABLE to debuggable,
|
||||
REQUEST_LEGACY_EXTERNAL_STORAGE to true
|
||||
REQUEST_LEGACY_EXTERNAL_STORAGE to true,
|
||||
VM_SAFE_MODE to true,
|
||||
USE_EMBEDDED_DEX to true,
|
||||
EXTRACT_NATIVE_LIBS to true,
|
||||
)
|
||||
) {
|
||||
private var addDebuggable = debuggable
|
||||
private var addLegacyStorage = true
|
||||
private var addVmSafeMode = true
|
||||
private var addUseEmbeddedDex = true
|
||||
private var addExtractNativeLibs = true
|
||||
|
||||
override fun attr(ns: String?, name: String, resourceId: Int, type: Int, value: Any?) {
|
||||
if (name == NETWORK_SECURITY_CONFIG) return
|
||||
if (name == REQUEST_LEGACY_EXTERNAL_STORAGE) addLegacyStorage = false
|
||||
if (name == VM_SAFE_MODE) addVmSafeMode = false
|
||||
if (name == USE_EMBEDDED_DEX) addUseEmbeddedDex = false
|
||||
if (name == EXTRACT_NATIVE_LIBS) addExtractNativeLibs = false
|
||||
if (name == DEBUGGABLE) addDebuggable = false
|
||||
super.attr(ns, name, resourceId, type, value)
|
||||
}
|
||||
|
|
@ -152,6 +158,14 @@ object ManifestPatcher {
|
|||
super.attr(ANDROID_NAMESPACE, VM_SAFE_MODE, android.R.attr.vmSafeMode, TYPE_INT_BOOLEAN, 1)
|
||||
}
|
||||
|
||||
if (addExtractNativeLibs) super.attr(
|
||||
ANDROID_NAMESPACE,
|
||||
EXTRACT_NATIVE_LIBS,
|
||||
android.R.attr.extractNativeLibs,
|
||||
TYPE_INT_BOOLEAN,
|
||||
1
|
||||
)
|
||||
|
||||
super.end()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue