Google Play 服务使 apk 太大 [英] Google Play Services makes apk too big

查看:40
本文介绍了Google Play 服务使 apk 太大的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经安装了 Google Play 服务并创建了一个 Hello World 应用程序来测试一切正常,我认为应用程序大小太大:4.98 MB.我正在使用 Android Studio,并且已按照 android 开发人员网站中的详细说明进行操作.

这是我的 gradle 文件:

应用插件:'android'安卓 {compileSdkVersion 19构建工具版本19.0.1"默认配置{minSdk 版本 15目标SDK版本19版本代码 1版本名称1.0"}构建类型{释放 {runProguard 假proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'}}}依赖{编译文件树(目录:'libs',包括:['*.jar'])编译 'com.google.android.gms:play-services:4.3.23'}

编辑

这是我的 proguard 文件:

-keep class * extends java.util.ListResourceBundle {受保护的对象[][] getContents();}- 保持公共类 com.google.android.gms.common.internal.safeparcel.SafeParcelable {公共静态最终 *** NULL;}-keepnames @com.google.android.gms.common.annotation.KeepName 类 *-keepclassmembernames 类 * {@com.google.android.gms.common.annotation.KeepName *;}-keepnames 类 * 实现 android.os.Parcelable {公共静态最终**创造者;}

** 编辑 2 **

我已经使用最新版本的 Intellij Idea 安装了 Google Play 服务,现在 apk 是 3.52 MB.我不知道这是否是可以接受的尺寸.

这正常吗?

解决方案

不,这不正常 - 我的 GPSTest 应用程序 包含 Google Play 地图服务在使用 Proguard 进行混淆后只有 808KB - 当前版本(添加另一个库后)在混淆后约为 1,497KB.

我建议使用以下步骤从命令行导出 APK,以避免 Android Studio 出现潜在问题:

  1. 在命令行转到项目的根目录
  2. 运行gradlew assembleRelease
  3. /app/build/apk文件夹中找到经过签名和混淆的APK

如果您通过 Android Studio 导出 APK,请注意有一个 已知问题 默认情况下,Android Studio 将使用 assembleDebug 任务而不是 assembleRelease 任务导出.因此,build.gradle 文件中用于运行 Proguard 的任何特定于发布 buildType 的配置都不会被执行.

作为通过 Android Studio 导出的解决方法,您可以通过以下步骤更改默认构建变体:

  1. 在 Android Studio 中,打开查看->工具窗口->构建变体"
  2. 在打开的窗口中,将Build Variant"从 debug 更改为 release.

现在,当您执行Build->Generate Signed APK..."时,Android Studio 应该运行发行版 Build Variant,如果您在 build.gradle 中正确配置了 Proguard,它应该会运行 Proguard.您可以在正常调试应用的同时改回 debug 变体.

如果你想从 GPSTest 复制我的设置,这里是 proguard.cfg:

-optimizationpasses 5-dontusemixedcaseclassnames-不要跳过非公共图书馆类-不要预验证-详细-优化 !code/simplification/arithmetic,!field/*,!class/merging/*- 保持公共类 * 扩展 android.app.Activity- 保持公共类 * 扩展 android.app.Application- 保持公共类 * 扩展 android.preference.Preference-keepclasseswithmembers 类 * {本机<方法>;}-keepclasseswithmembers 类 * {公共 <init>(android.content.Context, android.util.AttributeSet);}-keepclasseswithmembers 类 * {公共<init>(android.content.Context, android.util.AttributeSet, int);}-keepclassmembers 枚举 * {公共静态 **[] 值();公共静态 ** valueOf(java.lang.String);}-keep 类 * 实现 android.os.Parcelable {公共静态最终 android.os.Parcelable$Creator *;}-保持类 * 扩展 java.util.ListResourceBundle {受保护的对象[][] getContents();}-dontwarn **CompatHoneycomb-dontwarn **CompatCreatorHoneycombMR2-不要警告 **AccessibilityServiceInfoCompatJellyBeanMr2-不要警告 android.support.v4.view.**-不要警告 android.support.v4.media.**-不要警告 com.actionbarsherlock.internal.**-保持类android.support.v4.** { *;}-keepattributes *注解*- 保持公共类 * 扩展 android.view.View- 保持公共类 * 扩展 android.view.ViewGroup- 保持公共类 * 扩展 android.support.v4.app.Fragment-keepclassmembers 类 * 扩展 com.actionbarsherlock.ActionBarSherlock {<init>(android.app.Activity, int);}

... 和 build.gradle:

应用插件:'android'安卓 {compileSdkVersion 19构建工具版本19.0.0"默认配置{minSdk 版本 8目标SDK版本19}如果(project.hasProperty(secure.properties")&&新文件(project.property("secure.properties")).exists()) {属性道具 = 新属性()props.load(new FileInputStream(file(project.property("secure.properties"))))签名配置{调试{存储文件文件(gpstest.debug.keystore")}释放 {存储文件文件(道具['key.store'])keyAlias 道具['key.alias']storePassword "askmeler"keyPassword "askmeler"}}} 别的 {签名配置{调试{存储文件文件(gpstest.debug.keystore")}释放 {//这里没有什么}}}构建类型{释放 {runProguard 真proguardFile 'proguard.cfg'签名配置signingConfigs.release}}}任务 askForPasswords <<{//必须创建 String 因为 System.readPassword() 返回 char[]//(并且在下面分配它会默默地失败)def storePw = new String(System.console().readPassword("\nKeystore 密码:"))def keyPw = new String(System.console().readPassword("Key password:"))android.signingConfigs.release.storePassword = storePwandroid.signingConfigs.release.keyPassword = keyPw}tasks.whenTaskAdded { theTask ->if (theTask.name.equals("packageRelease")) {theTask.dependsOn "askForPasswords"}}依赖{编译项目(':ShowcaseViewLibrary')编译 'com.google.android.gms:play-services:3.2.65'编译'com.actionbarsherlock:actionbarsherlock:4.4.0@aar'编译'org.jraf:android-switch-backport:1.2'编译 'com.google.maps.android:android-maps-utils:0.2.1'}

如果您想将其用作示例,则整个 GPSTest 源代码可在 Github 上获得.>

编辑

在使用 Google Play 服务 v6.5 或更高版本的功能时帮助缩小 APK 的另一种方法是仅包含您实际使用的 Google Play 服务中功能的库.

例如,如果您使用的唯一 Google Play 服务 API 是 Maps API v2,而不是在 build.gradle 中包含整个 Google Play 服务库:

编译'com.google.android.gms:play-services:7.8.0'

...您可以只包含 Maps API v2 部分:

编译'com.google.android.gms:play-services-maps:7.8.0'

请参阅 Google Play 服务 -有选择地将 API 编译到您的可执行文件中" 部分以了解您可以拆分哪些 API 的详细信息.以下是截至 2015 年 9 月的列表:

  • Google+ com.google.android.gms:play-services-plus:7.8.0
  • Google 帐户登录 com.google.android.gms:play-services-identity:7.8.0
  • Google Actions,基本客户端库 com.google.android.gms:play-services-base:7.8.0
  • Google 应用索引com.google.android.gms:play-services-appindexing:7.8.0
  • Google 应用邀请 com.google.android.gms:play-services-appinvite:7.8.0
  • Google Analytics com.google.android.gms:play-services-analytics:7.8.0
  • Google Cast com.google.android.gms:play-services-cast:7.8.0
  • Google Cloud Messaging com.google.android.gms:play-services-gcm:7.8.0
  • Google 云端硬盘 com.google.android.gms:play-services-drive:7.8.0
  • Google Fit com.google.android.gms:play-services-fitness:7.8.0
  • Google 位置、活动识别和地点 com.google.android.gms:playservices-location:7.8.0
  • Google 地图 com.google.android.gms:play-services-maps:7.8.0
  • Google 移动广告 com.google.android.gms:play-services-ads:7.8.0
  • Mobile Vision com.google.android.gms:play-services-vision:7.8.0
  • Google Nearby com.google.android.gms:play-services-nearby:7.8.0
  • Google 全景查看器 com.google.android.gms:play-services-panorama:7.8.0
  • Google Play 游戏服务 com.google.android.gms:play-services-games:7.8.0
  • SafetyNet com.google.android.gms:play-services-safetynet:7.8.0
  • Google 电子钱包 com.google.android.gms:play-services-wallet:7.8.0
  • Android Wear com.google.android.gms:play-services-wearable:7.8.0

I have installed Google Play Services and created a Hello World app to test that everything is working fine and I think the application size is too big: 4.98 MB. I'm using Android Studio and I've followed the instructions detailed in the android developers web.

This is my gradle file:

apply plugin: 'android'

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.1"

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.google.android.gms:play-services:4.3.23'
}

EDIT

This is my proguard file:

-keep class * extends java.util.ListResourceBundle {
    protected Object[][] getContents();
}

-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
    public static final *** NULL;
}

-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
    @com.google.android.gms.common.annotation.KeepName *;
}

-keepnames class * implements android.os.Parcelable {
   public static final ** CREATOR;
}

** EDIT 2 **

I've installed Google Play Services using the last version of Intellij Idea, and now the apk is 3.52 MB. I don't know if this is an acceptable size.

Is this normal?

解决方案

No, that's not normal - earlier builds of my GPSTest app that included Google Play Services for maps were only 808KB after being obfuscated using Proguard- current version (after adding another library) is around 1,497KB after obfuscation.

I would recommend exporting the APK from the command line using the following steps to avoid potential issues with Android Studio:

  1. Go to root of the project at the command line
  2. Run gradlew assembleRelease
  3. Find the signed and obfuscated APK in /app/build/apk folder

If you are exporting the APK via Android Studio, be aware that there is a known issue where Android Studio will export using the assembleDebug task instead of the assembleRelease task by default. As a result, any configurations in your build.gradle file for running Proguard that are specific to the release buildType won't be executed.

As a workaround for exporting via Android Studio, you can change the default Build Variant via the following steps:

  1. In Android Studio, open "View->Tool Windows->Build Variants"
  2. In the window that opens, change "Build Variant" from debug to release.

Now when you do "Build->Generate Signed APK...", Android Studio should run the release Build Variant, which should run Proguard if you have it configured correctly in build.gradle. You can change back to debug variant while debugging your app on a normal basis.

If you want to replicate my settings from GPSTest, here's the proguard.cfg:

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.preference.Preference

-keepclasseswithmembers class * {
    native <methods>;
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

-keep class * extends java.util.ListResourceBundle {
    protected Object[][] getContents();
}

-dontwarn **CompatHoneycomb
-dontwarn **CompatCreatorHoneycombMR2
-dontwarn **AccessibilityServiceInfoCompatJellyBeanMr2
-dontwarn android.support.v4.view.**
-dontwarn android.support.v4.media.**
-dontwarn com.actionbarsherlock.internal.**
-keep class android.support.v4.** { *; }
-keepattributes *Annotation*
-keep public class * extends android.view.View
-keep public class * extends android.view.ViewGroup
-keep public class * extends android.support.v4.app.Fragment

-keepclassmembers class * extends com.actionbarsherlock.ActionBarSherlock {
    <init>(android.app.Activity, int);
}

... and build.gradle:

apply plugin: 'android'

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.0"

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 19
    }

    if (project.hasProperty("secure.properties")
            && new File(project.property("secure.properties")).exists()) {

        Properties props = new Properties()
        props.load(new FileInputStream(file(project.property("secure.properties"))))

        signingConfigs {
            debug {
                storeFile file("gpstest.debug.keystore")
            }

            release {
                storeFile file(props['key.store'])
                keyAlias props['key.alias']
                storePassword "askmelater"
                keyPassword "askmelater"
            }
        }
    } else {
        signingConfigs {
            debug {
                storeFile file("gpstest.debug.keystore")
            }

            release {
                // Nothing here
            }
        }
    }

    buildTypes {
        release {
            runProguard true
            proguardFile 'proguard.cfg'
            signingConfig signingConfigs.release
        }
    }
}

task askForPasswords << {
    // Must create String because System.readPassword() returns char[]
    // (and assigning that below fails silently)
    def storePw = new String(System.console().readPassword("\nKeystore password: "))
    def keyPw = new String(System.console().readPassword("Key password: "))

    android.signingConfigs.release.storePassword = storePw
    android.signingConfigs.release.keyPassword = keyPw
}

tasks.whenTaskAdded { theTask ->
    if (theTask.name.equals("packageRelease")) {
        theTask.dependsOn "askForPasswords"
    }
}

dependencies {
    compile project(':ShowcaseViewLibrary')
    compile 'com.google.android.gms:play-services:3.2.65'
    compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar'
    compile 'org.jraf:android-switch-backport:1.2'
    compile 'com.google.maps.android:android-maps-utils:0.2.1'
}

Entire GPSTest source code is available on Github if you want to use it as a sample.

EDIT

Another way to help shrink your APK when using features from Google Play Services v6.5 or higher is to include only the library for the feature in Google Play Services that you're actually using.

For example, if the only Google Play Services API you're using is the Maps API v2, instead of including the entire Google Play Services library in build.gradle:

compile 'com.google.android.gms:play-services:7.8.0'

...you can just include the Maps API v2 portion:

compile 'com.google.android.gms:play-services-maps:7.8.0'

See the Google Play Services - "Selectively compiling APIs into your executable" section for details on what APIs you can split out. Here's a list as of Sept. 2015:

  • Google+ com.google.android.gms:play-services-plus:7.8.0
  • Google Account Login com.google.android.gms:play-services-identity:7.8.0
  • Google Actions, Base Client Library com.google.android.gms:play-services-base:7.8.0
  • Google App Indexing com.google.android.gms:play-services-appindexing:7.8.0
  • Google App Invites com.google.android.gms:play-services-appinvite:7.8.0
  • Google Analytics com.google.android.gms:play-services-analytics:7.8.0
  • Google Cast com.google.android.gms:play-services-cast:7.8.0
  • Google Cloud Messaging com.google.android.gms:play-services-gcm:7.8.0
  • Google Drive com.google.android.gms:play-services-drive:7.8.0
  • Google Fit com.google.android.gms:play-services-fitness:7.8.0
  • Google Location, Activity Recognition, and Places com.google.android.gms:playservices-location:7.8.0
  • Google Maps com.google.android.gms:play-services-maps:7.8.0
  • Google Mobile Ads com.google.android.gms:play-services-ads:7.8.0
  • Mobile Vision com.google.android.gms:play-services-vision:7.8.0
  • Google Nearby com.google.android.gms:play-services-nearby:7.8.0
  • Google Panorama Viewer com.google.android.gms:play-services-panorama:7.8.0
  • Google Play Game services com.google.android.gms:play-services-games:7.8.0
  • SafetyNet com.google.android.gms:play-services-safetynet:7.8.0
  • Google Wallet com.google.android.gms:play-services-wallet:7.8.0
  • Android Wear com.google.android.gms:play-services-wearable:7.8.0

这篇关于Google Play 服务使 apk 太大的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆