使用 Proguard 删除 Google Play Services 库中未使用的类
Posted
技术标签:
【中文标题】使用 Proguard 删除 Google Play Services 库中未使用的类【英文标题】:Using Proguard to remove unused classes in Google Play Services library 【发布时间】:2015-02-24 08:38:33 【问题描述】:我正在尝试从 Google Play Services
库中删除未使用的类。我创建了具有单个空活动的全新 android 项目。该项目不使用来自Google Play Services
库的任何内容。所以我希望,当我构建版本(包括在我的配置中运行 proguard)时,与有/没有 play-services
依赖项的构建相比,我会发现二进制大小没有区别。但实际上,我看到 apk
大小的差异约为 700 KB。
我找到了relatively complex solution, using gradle script,其中涉及重新打包 play-services.jar 文件。此外,此解决方案需要明确指定每个不会使用的包。但我不明白为什么proguard
不适合我的情况?
build.gradle:
apply plugin: 'com.android.application'
android
compileSdkVersion 21
buildToolsVersion "21.1.1"
defaultConfig
minSdkVersion 10
targetSdkVersion 21
buildTypes
release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
dependencies
// !!! when I comment the line below, release APK is 700 KB smaller !!! //
compile 'com.google.android.gms:play-services:6.5.87'
proguard-rules.pro:
-assumenosideeffects class android.util.Log
public static *** d(...);
AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.noplayservices">
<application android:allowBackup="true"
android:label="@string/app_name"
android:icon="@drawable/ic_launcher"
android:theme="@style/AppTheme">
<activity android:name=".ui.activities.MainActivity" android:icon="@drawable/ic_launcher">
<intent-filter>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.java:
package com.test.noplayservices.ui.activities;
import android.app.Activity;
import android.os.Bundle;
import com.test.noplayservices.R;
public class MainActivity extends Activity
@Override
public void onCreate(Bundle savedInstance)
super.onCreate(savedInstance);
setContentView(R.layout.main_activity);
【问题讨论】:
Proguard 会删除未使用的类,但我不确定它是否会删除public static
数据,或者 static initializers
会发生什么情况。我敢打赌这些课程没有被删除。作为 google play 服务的一个庞大的库,其所有类都相互关联,我想该方法将类似于您所指出的:只需尝试从库 jar 中提取您需要的类。顺便说一句-我使用的旧罐子比现在的小得多,去年它们的大小增长了 3 倍。
另外,您可以做的是将您的 700kb APK 上传到像 decompileandroid.com 这样的网站,将您的 APK 反编译为源代码,然后查看包含哪些 GPS 类并尝试了解原因.至少您可以定义规则来排除这些类。记得禁用混淆以清楚地看到包含的类!
您可能还想添加shrinkResources true
- 请参阅here
@miav 谢谢!这正是我需要的!
@miav,不幸的是,它并没有真正改变什么。实际上,从play-services
我只需要ads
和analytics
。 ads
可作为独立包提供,但 analytics
是 base
包的一部分,其中包含 600KB 资源(ads
或 analytics
均未使用这些资源)。所以我预计 shirnkResources 将删除大部分 600KB,但它没有。我还有 700KB APK
【参考方案1】:
从 Google Play 服务 6.5 版及更高版本开始,您可以选择要使用的单个 API,然后只导入这些 API。也许这会帮助您稍微减小 APK 的大小。这是一个列表:
Google+ com.google.android.gms:play-services-plus:6.5.+
Google Account Login com.google.android.gms:play-services-identity:6.5.+
Google Activity Recognition com.google.android.gms:play-services-location:6.5.+
Google App Indexing com.google.android.gms:play-services-appindexing:6.5.+
Google Cast com.google.android.gms:play-services-cast:6.5.+
Google Drive com.google.android.gms:play-services-drive:6.5.+
Google Fit com.google.android.gms:play-services-fitness:6.5.+
Google Maps com.google.android.gms:play-services-maps:6.5.+
Google Mobile Ads com.google.android.gms:play-services-ads:6.5.+
Google Panorama Viewer com.google.android.gms:play-services-panorama:6.5.+
Google Play Game services com.google.android.gms:play-services-games:6.5.+
Google Wallet com.google.android.gms:play-services-wallet:6.5.+
Android Wear com.google.android.gms:play-services-wearable:6.5.+
Google Actions
Google Analytics
Google Cloud Messaging com.google.android.gms:play-services-base:6.5.+
你可以看到更多关于这个here。
【讨论】:
这个解决方案加上@miav 建议的shrinkResources
应该可以完成工作!谢谢!以上是关于使用 Proguard 删除 Google Play Services 库中未使用的类的主要内容,如果未能解决你的问题,请参考以下文章
Proguard 使用 Google Play 服务库返回错误
使用 Proguard 在 dist 上混淆 Play 2 Web 应用程序?
使用 google-play-services 进行 Proguard
使用 proguard 混淆后,使用 google guice 注入不再起作用