【问题标题】:instant app getting below 4mb difficulties. how to reduce apk size即时应用程序的难度低于 4mb。如何减小apk大小
【发布时间】:2018-06-25 07:19:51
【问题描述】:

我在使 apk 低于 4mb 时遇到了困难。 检查生成的免安装应用 APK 后 我看到 com.google.android.gms.internal 几乎是 1.4mb。 我只是找不到这个大块的原因。一定是某种依赖。

我的基本清单文件如下所示:

dependencies {

api "com.android.support:design:$rootProject.supportLib"
api "com.android.support:support-fragment:$rootProject.supportLib"

api "com.android.support:appcompat-v7:$rootProject.supportLib"
api "com.android.support:recyclerview-v7:$rootProject.supportLib"
api "com.android.support:cardview-v7:$rootProject.supportLib"

api 'com.android.support.constraint:constraint-layout:1.0.2'
api "com.google.code.gson:gson:$rootProject.gson"
api "com.google.firebase:firebase-core:$rootProject.googleLibs"
api "com.google.firebase:firebase-ads:$rootProject.googleLibs"
api "com.google.firebase:firebase-appindexing:$rootProject.googleLibs"
api "com.google.android.gms:play-services-auth:$rootProject.googleLibs"
api "com.android.support:multidex:$rootProject.multidex"
api "com.github.bumptech.glide:glide:$rootProject.glide"
annotationProcessor "com.github.bumptech.glide:compiler:$rootProject.glide"
api "com.loopj.android:android-async-http:$rootProject.asyncHttp"

api "org.greenrobot:eventbus:$rootProject.greenRobotEventBus"
api "com.vincentbrison.openlibraries.android:dualcache:$rootProject.dualcache"
api('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') {
    transitive = true;
}

【问题讨论】:

  • 运行./gradlew <your_module>:dependencies 来查看模块中的传递依赖项有时会很有用....这可以显示您没有意识到的依赖项以及版本不匹配。
  • 谢谢。是的,我一直在运行该命令以查看 deps 的来源。我已经从 5mb 降到 3.2。但我只是看不到任何与 com.google.android.gms.internal 相关的东西必须是某种谷歌库。为什么这么大?
  • 您在使用 ProGuard 吗?您会发现您实际上需要使用它来缩小即时应用程序的大小。您可能知道 4MB 限制适用于基础和功能 apk 的组合。
  • 是的。是的,proguard正在使用中。尽可能优化它。资源也一样。不要认为我可以进一步优化这些。我真的需要摆脱一些库,因此也可能是功能。但我真的很想知道为什么谷歌的东西这么大。我很确定我不需要它。
  • 除了检查developer.android.com/topic/performance/reduce-apk-size.html 以了解您还能做什么之外,kabuko 关于配置拆分的提示可能是您的下一个最佳选择。

标签: android android-gradle-plugin dependencies android-instant-apps


【解决方案1】:

我刚刚完成了相同的操作,并将 Instant Apps 的大小从 13MB 提高到了 4MB。

经过这么多头痛和无数小时后,我发现以下软件包的大小取决于您包含的依赖项。

  1. com.google.android.gms.internal
  2. android.support.v4.internal
  3. android.support.v7.internal

例如,如果您排除广告依赖项,则内部大小将减少至少 500kb。 Android 支持库也是如此,排除 CardView 并查看支持的内部大小缩小。

我将逐步列出我在为一个超大型应用程序的多功能即时应用程序模块中遇到的所有麻烦:

移动仅在主应用程序中使用的依赖项

在您的情况下,以下 2 项对于 Instant App 绝对没用,只能在主应用程序中使用:

api "com.google.firebase:firebase-appindexing:$rootProject.googleLibs"
api "com.android.support:multidex:$rootProject.multidex"

将它们移动到主应用程序,如果代码与您的视图相结合,移动 Appindexing 可能会很困难,但您必须修复它。就我而言,我必须从基本模块中的视图实例化 AppIndexing,所以我使用 Otto (EventBus) 来实现。在基本模块中创建一个事件,触发它并在主应用程序的 AppIndexing 帮助程序类中捕获。

从所有软件包中明确排除 google 支持组

这可能看起来很荒谬,但大小不言而喻,通过明确排除更改所有 Google/Android 支持依赖项:

api("com.android.support:design:$rootProject.supportLib") {
    exclude group: 'com.android.support'
}
api("com.android.support:support-fragment:$rootProject.supportLib") {
    exclude group: 'com.android.support'
}
api("com.android.support:appcompat-v7:$rootProject.supportLib") {
    exclude group: 'com.android.support'
}
api("com.android.support:recyclerview-v7:$rootProject.supportLib") {
    exclude group: 'com.android.support'
}
api("com.android.support:cardview-v7:$rootProject.supportLib") {
    exclude group: 'com.android.support'
}
api('com.android.support.constraint:constraint-layout:1.0.2') {
    exclude group: 'com.android.support'
}
api("com.google.firebase:firebase-core:$rootProject.googleLibs") {
    exclude group: 'com.android.support'
}
api("com.google.firebase:firebase-ads:$rootProject.googleLibs") {
    exclude group: 'com.android.support'
}
api("com.google.firebase:firebase-appindexing:$rootProject.googleLibs") {
    exclude group: 'com.android.support'
}
api("com.google.android.gms:play-services-auth:$rootProject.googleLibs") {
    exclude group: 'com.android.support'
}

为每个模块启用 Proguard

正如其他人提到的,enable proguard for each module。 proguard 减少了大约 25% 的原始 13MB。

排除不会在免安装应用中使用的功能

登录:

对我们来说,登录功能不需要在 Instant App 中。因此,我将与登录/身份验证相关的所有内容移至主应用程序,并使用事件总线在基本模块需要的地方触发操作。例如,导航抽屉中的登录/注销操作(在即时应用程序中隐藏但在主应用程序中可见)存在于基本模块中。所以我为每个事件触发一个事件并在主应用程序模块中捕获它以显示登录屏幕或处理注销。

这使我可以从基本模块中排除 com.google.android.gms:play-services-auth 依赖项,从而进一步减小 gms 内部大小。

广告:

我们不得不将广告从我们的基本模块移到主应用程序中,仅出于尺寸目的。我们使用类似的技术(事件总线)来调用以从基本模块渲染广告并通过帮助程序类在主应用程序中进行实际渲染。

这使我们可以删除 com.google.firebase:firebase-corecom.google.firebase:firebase-ads

P.S:功能排除完全取决于您的需求/想要/妥协。我们做出这些决定是因为我们希望我们所有的创收功能都在 Instant App 中。所以只要我们能赚钱,我们就不在乎广告或登录。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    看起来这是 com.google.firebase:firebase-ads 的依赖树:

    \--- com.google.firebase:firebase-ads:11.8.0
         +--- com.google.android.gms:play-services-ads:11.8.0
         |    +--- com.google.android.gms:play-services-ads-lite:11.8.0
    

    play-services-ads 是一个大型库(为“com.google.android.gms.internal”中的大量代码提供了帮助),您可以通过将其换成smaller library 来获得成功。 (当然,我建议提交问题以获得官方支持的“精简版”“firebase-ads”。)

    【讨论】:

      【解决方案3】:

      我相当肯定com.google.android.gms.internal 包含公共 gms 包使用的通用代码,在您的情况下为 com.google.android.gms:play-services-auth(您可能用于 Smart Lock)并且无法删除它。如果您已经降至 3.2MB,老实说,我怀疑它很难变得更小。您似乎同时使用 Play Services 和支持库。在这两者之间,很难进一步降低它。我发现有用的另一件事是使用configuration splits,尤其是密度拆分。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-04
        • 1970-01-01
        • 2014-09-25
        • 1970-01-01
        • 2022-11-10
        • 2018-12-01
        • 1970-01-01
        • 2020-11-10
        相关资源
        最近更新 更多