Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Proguard to remove unused classes in Google Play Services library

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);
    }
}
like image 827
Denis Itskovich Avatar asked Dec 27 '14 12:12

Denis Itskovich


1 Answers

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.

like image 90
Renan Ferrari Avatar answered Oct 09 '22 13:10

Renan Ferrari