You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从极简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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 21:05:55