Yaroslav Mytkalyk
Yaroslav Mytkalyk

Reputation: 17115

Proguard with Gradle messes id's defined

The problem occurs only when built with proguard + gradle. If exported from android tools and proguard - all references are mapped correctly.

Problem:

I have defined some id's in a library project

<resources>
    <item type="id" name="background" />
</resources>

And the activity layout is in main project

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@id/background"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scaleType="centerCrop"
    android:src="@drawable/splash"
    tools:ignore="ContentDescription" />

The NullPointer after being built with proguard is thrown at main project's Activity

this.findViewById(R.id.background).setOnClickListener(new View.OnClickListener() {

Don't suggest me redefining id's because it's a wrong approach and crashes anyway.

android:id="@+id/background"

UPDATE: it turns out it messes even id's defined in layout of main project like

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/backgroundTEST"/>

Also crashes with NullPointerException.I thought it was because of library project because the very first one that fails was one from a library project.

The configuration is as follows

The $ANDROID_HOME/tools/proguard/proguard-android.txt is

-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose

-dontoptimize
-dontpreverify

-keepattributes *Annotation*
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclassmembers public class * extends android.view.View {
   void set*(***);
   *** get*();
}

-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}

-keepclassmembers class **.R$* {
    public static <fields>;
}

-dontwarn android.support.**

The proguard-project.txt for my project

-injars      bin/classes
-injars      libs
-outjars     bin/classes-processed.jar

-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.support.v4.app.FragmentActivity

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

From build.gradle

buildTypes {
    release {
        runProguard true
        proguardFile getDefaultProguardFile('proguard-android.txt')
        proguardFile 'proguard-project.txt'
        signingConfig signingConfigs.release
    }
}

My concern was, maybe it does not include getDefaultProguardFile('proguard-android.txt'). Well, for an experiment I've copy-pasted proguard-android.txt contents to proguard-project.txt And still after

gradle clean
gradle assembleRelease

it crashed.

Upvotes: 2

Views: 1384

Answers (2)

Tina Roh
Tina Roh

Reputation: 136

Try adding the following as well:

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

Upvotes: 1

Szymon
Szymon

Reputation: 43023

I have that in my Proguard config to cater for R class

-keepclassmembers class **.R$* {
    public static <fields>;
}

Upvotes: 1

Related Questions