Google Play服务使apk太大了

时间:2014-03-26 18:42:15

标签: android android-studio google-play-services

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

这是我的gradle文件:

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'
}

修改

这是我的proguard文件:

-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;
}

**编辑2 **

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

这是正常的吗?

2 个答案:

答案 0 :(得分:15)

不,这不正常 - 我的GPSTest app的早期版本(包括用于地图的Google Play服务)在使用Proguard进行混淆后仅为808KB - 当前版本(添加另一个库后)在混淆后大约为1,497KB。 / p>

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

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

    如果您要通过Android Studio导出APK,请注意默认情况下有known issue Android Studio将使用assembleDebug任务导出而不是assembleRelease任务。因此,将不会执行特定于发行版buildType的build.gradle文件中用于运行Proguard的任何配置。

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

    1. 在Android Studio中,打开“View-> Tool Windows-> Build Variants”
    2. 在打开的窗口中,将“构建变体”从debug更改为release
    3. 现在当您执行“Build-> Generate Signed APK ...”时,Android Studio应该运行Build Variant版本,如果您在build.gradle中正确配置了它,则应运行Proguard。您可以在正常情况下调试应用时更改回debug变体。

      如果您想从GPSTest复制我的设置,请点击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);
      }
      

      ...和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'
      }
      

      如果您想将其用作样本,则整个GPSTest源代码均为available on Github

      修改

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

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

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

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

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

      有关可以拆分的API的详细信息,请参阅Google Play Services - "Selectively compiling APIs into your executable"部分。这是截至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操作,基本客户端库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邀请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
      • 移动视觉com.google.android.gms:play-services-vision:7.8.0
      • Google附近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游戏服务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

答案 1 :(得分:2)

好的,最后我遇到了这个问题(感谢@Sean Barbeau)。这是我模块的build.gradle文件。在BuildTypes部分我有release而不是debug我正在部署调试版本...我已经改变了,现在我的应用程序只有1.17 MB!

buildTypes {
    debug {
        runProguard true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
    }
}

修改

正如@SeanBarbeau指出的那样,runProguard在调试模式下设置为true。如果我设置false,那么我的应用程序又是大的(5 MB大小)。