如何从极简Hello World Android项目中移除V4 Support Library
问题描述
我在复现《构建最小APK文件》教程的步骤,目的是学习相关技术的核心原理,但教程中的APK无法在最新Android版本安装。复现时我发现生成的APK大小无法低于565KB,其中classes.dex占255KB、包含246个类,远达不到教程提及的100KB以下。我已尝试在Gradle配置中排除support-v4,但仍发现引入了V4 Support Library的类:
> dexdump classes.dex | grep 'Class descr' | grep support Class descriptor : 'Landroid/support/v4/app/RemoteActionCompatParcelizer;' Class descriptor : 'Landroid/support/v4/graphics/drawable/IconCompatParcelizer;'
请问如何彻底移除该库?以下是我的项目文件:
app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <application android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" tools:targetApi="31"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
settings.gradle.kts
pluginManagement { repositories { google { content { includeGroupByRegex("com\\.android.*") includeGroupByRegex("com\\.google.*") includeGroupByRegex("androidx.*") } } mavenCentral() gradlePluginPortal() } } dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } } rootProject.name = "basic_views_activity" include(":app")
根目录build.gradle.kts
// Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { alias(libs.plugins.android.application) apply false }
app/build.gradle.kts
plugins { alias(libs.plugins.android.application) } android { namespace = "com.example.basic_views_activity" compileSdk = 34 configurations.all { exclude(group = "com.android.support", module = "support-v4") } defaultConfig { applicationId = "com.example.basic_views_activity" minSdk = 28 targetSdk = 34 versionCode = 1 versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } buildTypes { debug { isMinifyEnabled = true isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } release { isMinifyEnabled = true isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) } } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } buildFeatures { viewBinding = true } } dependencies { implementation(libs.constraintlayout) }
app/proguard-rules.pro
-keep class com.example.basic_views_activity.** { *; } -keep class com.example.basic_views_activity.MainActivity { *; }
app/src/main/java/com/example/basic_views_activity/MainActivity.java
package com.example.basic_views_activity; import android.os.Bundle; import com.example.basic_views_activity.databinding.ActivityMainBinding; import android.app.Activity; public class MainActivity extends Activity { private ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); } }
app/src/main/res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="Hello World!" />
解决方案
1. 清理Manifest冗余配置
Manifest中的备份、资源提取配置会自动引入support类,直接删除:
android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"- 暂时移除
android:icon和android:roundIcon,用系统默认图标减少资源体积
修改后的Manifest:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
2. 关闭View Binding并简化MainActivity
布局仅含一个TextView,无需View Binding,关闭后可移除大量databinding相关类:
- 在
app/build.gradle.kts中修改buildFeatures:buildFeatures { viewBinding = false } - 修改MainActivity代码:
package com.example.basic_views_activity; import android.os.Bundle; import android.app.Activity; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
3. 全面排除support依赖并禁用Jetifier
在项目根目录创建/修改gradle.properties,添加以下配置:
android.useAndroidX=true android.enableJetifier=false
同时在app/build.gradle.kts扩大排除范围:
configurations.all { exclude(group = "com.android.support") exclude(group = "androidx.core") }
4. 优化ProGuard规则
当前规则过于宽松,修改app/proguard-rules.pro:
# 仅保留主Activity必要代码 -keep class com.example.basic_views_activity.MainActivity { *; } # 忽略support相关警告 -dontwarn android.support.** -dontnote android.support.**
5. 移除不必要的依赖
布局无需ConstraintLayout,删除app/build.gradle.kts中的对应依赖:
// 移除该行 implementation(libs.constraintlayout)
6. 删除冗余资源
- 删除
res/mipmap下所有图标文件 - 删除
res/xml下的backup_rules.xml和data_extraction_rules.xml - 简化
res/values/strings.xml:<resources> <string name="app_name">MinAPK</string> </resources>
完成以上步骤后,执行./gradlew clean assembleRelease重新构建APK,此时classes.dex中的support类会被彻底移除,APK大小将大幅降低,接近教程目标范围。
内容的提问来源于stack exchange,提问作者d33tah
相关产品推荐
相关产品推荐

