使用google-play-services_lib添加admob广告后,Android应用程序大小增加了。

6
我将发布两个版本的应用程序,一个收费版和一个免费版(包含AdMob广告)。除了在免费版中使用了google-play-service_lib来提供AdMob服务之外,这两个版本完全相同。
经过Proguard处理后,最终APK大小如下: 收费版:1,301,435字节 带广告版本:1,946,634字节
在免费版中,我只显示插页式广告。
以下是与google-play-service_lib相关的我的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;
}

有什么方法可以减小文件大小,比如删除一些-keep标记之类的东西吗?

编辑

使用apktool我发现Google Play服务包中的任何类都没有被收缩(包括com.google.android.gms.maps.*com.google.android.gms.games.*和许多其他我认为不需要用于广告管理的类)。

如何强制收缩一个类或者一个类组?

再次编辑

看起来Eclipse不会保存Proguard的输出,至少我在任何地方都找不到它。然后我配置了我的项目和库使用Ant进行构建以查看一些输出,但几乎无法察觉,这是两种情况:

 -whyareyoukeeping class com.google.android.gms.maps.GoogleMap

 [proguard] Explaining why classes and class members are being kept...
 [proguard] Printing usage to [...../bin/proguard/usage.txt]...
 [proguard] com.google.android.gms.maps.GoogleMap
 [proguard]   is not being kept.

至少我读到过说类没有被保留,尽管我可以通过apktool看到它!

 -whyareyoukeeping class com.google.android.gms.games.Games

 [proguard] Explaining why classes and class members are being kept...
 [proguard] Printing usage to [...../bin/proguard/usage.txt]...

这里没有提及给定的类。

我放弃了,因为一个插页式广告,我的应用程序大小增加了50%,尽管Google关于GPS表示:

如果您在构建过程中使用ProGuard,则客户端库具有轻量级占用空间,因此不会对应用程序的文件大小产生负面影响。

但我找不到任何指南!


1
不是真正的解决方案,只是可能有所帮助:您可以删除drawable-XXXX文件夹。它们仅包含登录/退出和+1按钮图像。我建议检查库许可证以确保符合Google的要求。 - sagis
@sagis +1!谢谢,这是一个有趣的观点。 - j.c
3个回答

13

这与proguard无关。 正如您所知,Google Play服务是闭源的。没有源代码,Proguard无法处理它。但是您可以手动缩小它。

1、从jar文件中删除未使用的类

在Google Play服务文件夹中(通常为sdk\extras\google\google_play_services\ libproject\google-play-services_lib\libs\),使用诸如7zip之类的zip文件管理器打开 google-play-services.jar,您可以找到许多文件夹,例如地图、游戏等。 如果您只使用广告,则这些都对您没有用。 因此,请将它们删除。 要小 心保留 ads、common、dynamic、internallocation 文件夹,否则显示广告时会出现 NoClassDefFoundError 错误。

2、如果您只使用广告,请从res文件夹中删除未使用的资源。

google-play-services_lib\res文件夹中的许多资源对您没有用,因此可以将其删除。 例如,values-af、values-am等。 您需要保留的是 color、drawable、 drawable-hdpivalues 文件夹。

3、现在在Eclipse中刷新并构建google-play-services_lib项目,然后再次刷新和构建您的项目。 现在您应该发现apk大小变小了。 我的apk在使用 Proguard 之前从 902kb 缩小到 480kb,在使用Proguard之后进一步缩小到330kb


1
你确定Proguard不能处理没有源代码的JAR文件吗?我认为它只使用.class文件而不是.java文件。 - Tomáš Hubálek
好的解决方案,值得推荐并且可行。比配置Gradle依赖或多dex要快得多。 - Vaiden
这导致了 com.android.dx.cf.iface.ParseException: 类名 (com/google/ads/AdRequest$ErrorCode) 与路径 (google-play-services/com/google/ads/AdRequest$ErrorCode.class) 不匹配。有什么想法吗? - tugce

4

你在build.gradle文件中使用了这行代码吗?

compile 'com.google.android.gms:play-services:6.+'

如果是,则在此处添加以下行。
compile 'com.google.android.gms:play-services-ads:6.+'

它可以将应用程序大小减小大约600kb。


2

你的proguard配置文件中的其他部分导致GPS类被保留。

请参考Proguard使用手册,特别是以下选项:

-whyareyoukeeping class_specification

如果您自己无法找到原因,可以使用该选项告诉您为什么保留了特定的类。


谢谢,我会看一下的。 - j.c
你需要特别保留通过反射构建的任何类。例如从XML引用的Activities或其他类。其余部分可以由Proguard解决,因为它会创建依赖关系图。 - William
我只需要展示AdMob插页式广告,不需要使用任何XML。我将com.google.android.gms.ads.*导入到我的代码中,没有其他的东西。 - j.c
我尝试使用proguard和-whyareyoukeeping class com.google..android.gsm.*...从eclipse->file->export,我在哪里可以找到输出?控制台没有显示任何新内容... - j.c
抱歉,我不使用Eclipse。但是当您运行Proguard时,它会生成输出(除了混淆的类)。请查看Eclipse放置构建输出的位置并阅读Proguard文档。 - William
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接