6

I'm trying to get rid of unused classes from Google Play Services library. I've created brand new android project with single empty activity. The project does not use anything from Google Play Services library. So I would expect, that when I build release (which includes running proguard in my configuration) I will see no difference in binary size comparing building with/without play-services dependency. But actually, I see ~700 KB difference in apk size.

I've found relatively complex solution, using gradle script, which involves repacking play-services.jar file. Also, this solution requires to specify explicitly each package which is not going to be used. But I don't understand why doesn't proguard do this work in my case?

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);
    }
}
Denis Itskovich
  • 4,383
  • 3
  • 32
  • 53
  • Proguard removes unused classes, but I'm not sure if it will remove `public static` data, or what happens with `static initializers`. I bet the classes are not removed. Being google play services a mammooth library with all its classes interrelated, I guess the approach will be similar to what you point: Just try to extract the classes you need from the library jar. BTW- I'm using an old jar that is much smaller than the current ones, they grew like 3 times in size in the last year. – rupps Dec 27 '14 at 13:13
  • also, what you can do, is to upload your 700kb APK to a website like http://www.decompileandroid.com/ , get your APK decompiled to source code, and see what GPS classes have been included and try to understand why. At the very least you could define rules to exclude those classes. Remember to disable obfuscationto clearly see the included classes ! – rupps Dec 27 '14 at 13:17
  • 1
    you might want to add `shrinkResources true` also - see [here](https://plus.google.com/u/0/+TorNorbye/posts/eHsStybrrBf) – natario Dec 28 '14 at 10:17
  • @miav, Unfortunately, it didn't really change something. Actually, from the `play-services` I need only `ads` and `analytics`. `ads` is available as a stand-alone package, but `analytics` is a part of `base` package, which contains 600KB of resources (which are not used either by `ads` or `analytics`). So I expected that shirnkResources will remove the most of 600KB, but It didn't. I still have 700KB APK – Denis Itskovich Dec 28 '14 at 10:33

1 Answers1

9

From Google Play Services version 6.5 and beyond you can select which individual APIs you want to use, and import just those ones. Maybe that will help you decrease the APK size a little bit. Here's a list:

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.+

You can see more about this here.

Renan Ferrari
  • 2,449
  • 5
  • 21
  • 26