I know this question has been asked a million times and yet, I couldn't find the answer to my specific situation. I have a library which has all of the code, and a couple of other modules that import the library.
-project
--mylibrary
---sr/main/java
----co/android/mylibrary
----BaseApp (extends MultidexApp)
--Application1
---sr/main/java
----co/android/app2
-----Android Manifest
--Application2
---sr/main/java
----co/android/app2
-----Android Manifest
And both the manifests use the base app like this.
<application
android:name="co.android.mylibrary.BaseApp"
android:allowBackup="false"
android:fullBackupContent="false"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:largeHeap="true"
android:theme="#style/AppTheme"
tools:replace="android:icon,android:theme, android:allowBackup">
And the build dependencies look like this:
dependencies {
releaseCompile project(path: ':mylibrary', configuration: 'release')
debugCompile project(path: ':mylibrary', configuration: 'debug')
}
My base app's method to initialize multidex:
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
try {
MultiDex.install(this);
}catch (RuntimeException e){}
}
Some of my proguard rules, that I've added at both locations (library and the application). These don't include some rules for 3rd party libraries and some of my own classes.
-keep public class * extends android.app.Activity
-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.view.View
-keep public class co.android.mylibrary.data.greendao.**{ *; }
So the app runs fine on my s8, but doesn't on some phones like the moto G. They would also run fine if Proguard is enabled and its shrinking resources, like for release builds. Another strange behavior I noticed is that, when I set my breakpoint on some parts of my code and run the release builds (with debuggable set to true), it would break on the s8, but not on the moto.
Why this strange behavior? Another question that I found super similar is unable to instantiate application - ClassNotFoundException. But still no resolution.
This is the complete log of the error. Ignore the package names.
Edit
After changing the way I compile the library on my application, based on suggestiongs from #Mostafa Anter:
compile project(path: ':mylibrary', configuration: 'debug')
It started giving me this error. I have my instant run turned off.
make base class extend Application
then inside onCreate method call this lineMultiDex.install(this);
Modify the module-level build.gradle file to enable multidex and add the multidex library as a dependency, as shown here:
android {
defaultConfig {
...
minSdkVersion 15
targetSdkVersion 26
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.1'
}
if you use JavaVersion.VERSION_1_8 please be sure that you use it in all modules
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Related
The negator (exclamation mark) in proguard should allow me to keep anthing but the apache libraries:
-keep class !org.apache.**
According to those answers. That's the way to go:
How to negate classname with Proguard
Enable Proguard for only two packages in large Android application
Android proguard Ignore All Classes except of one
Proguard Android do not obfuscate anything except few classes
Proguard: How to keep everything except specific condition?
Can we shrink all classes but only obfuscate some with proguard?
However, it obfuscates all classes in my APK.
That's part of my build.gradle (I have Android Studio 3.5.3)
compileSdkVersion 29
buildToolsVersion "29.0.2"
//...
buildTypes {
release {
minifyEnabled true
proguardFiles /*getDefaultProguardFile('proguard-android.txt'),*/ 'proguard-rules.pro'
// Enables resource shrinking, which is performed by the
// Android Gradle plugin.
shrinkResources false
}
}
dependencies {
//Utility libs
implementation 'org.apache.commons:commons-collections4:4.1'
implementation 'org.apache.commons:commons-lang3:3.4'
implementation group: 'commons-io', name: 'commons-io', version: '2.5'
}
After I added -printconfiguration to my proguard-rules.pro file I saw there are numerous -keep rules following my -keep class !org.apache.**
-printconfiguration
-keep class !org.apache.**
# Referenced at ***anonymized***\app\build\intermediates\merged_manifests\release\AndroidManifest.xml:180
-keep class android.support.v4.app.CoreComponentFactory { <init>(); }
# Referenced at ***anonymized***\app\build\intermediates\merged_manifests\release\AndroidManifest.xml:180
-keep class com.mycompany.MyApplication { <init>(); }
# Referenced at C:\Users\***anonymized***\.gradle\caches\transforms-2\files-2.1\7f5f0b3369d8fa8a72a20e2278ec0acc\appcompat-v7-28.0.0\res\layout\abc_action_menu_item_layout.xml:17
-keep class android.support.v7.view.menu.ActionMenuItemView { <init>(...); }
That approach suggested by Ezekiel Baniaga also didn't work. Instead it keeps everything including the apache packages:
proguard-rules.pro
-printconfiguration
-dontshrink
-dontoptimize
-dontobfuscate
-keep,allowshrinking,allowoptimization,allowobfuscation class org.apache.**
I had to add ,** to get it working. Thanks T. Neidhart!
-keep class !org.apache.**,**
The previous example preserved class names but still obfuscated members. So I had to add { *; }:
-keep class !org.apache.**,** { *; }
That's how I obfuscate multiple packages (I have to use them all in one keep rule!)
-keep class !org.apache.**, !org.zeroturnaround.**, !com.drew.**, ** { *; }
To find out what my problem is with -dontshrink -dontoptimize -dontobfuscate -keep,allowshrinking,allowoptimization,allowobfuscation class org.apache.** I could add -whyareyoukeeping according to https://www.guardsquare.com/en/products/proguard/manual/usage
You should file a bug report with the R8 project if this does not work anymore.
In order to keep using Proguard in the meantime, you can add this to your gradle.properties files:
android.enableR8=false
Further tests show that the implicit behavior of ProGuard is not implemented like that in R8.
So a rule like:
-keep class !org.apache.**
will implicitly keep all other classes when using ProGuard, but not when using R8. To achieve the same behavior with R8, change the rule to this:
-keep class !org.apache.**,**
I am failing to create a release build. Suddenly Android Studio started throwing below error.
Unexpected error while performing partial evaluation:
Class = [com/google/android/gms/d/lc]
Method = [a(Lcom/google/android/gms/d/kk;Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/google/android/gms/d/lh;Lcom/google/android/gms/d/en;Lcom/google/android/gms/d/lb;)Lcom/google/android/gms/d/kn;]
Exception = [java.lang.IllegalArgumentException] (Can't find common super class of [com/google/android/gms/d/kn] (with 1 known super classes) and [java/lang/String] (with 2 known super classes))
Unexpected error while preverifying:
Class = [com/google/android/gms/d/lc]
Method = [a(Lcom/google/android/gms/d/kk;Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/google/android/gms/d/lh;Lcom/google/android/gms/d/en;Lcom/google/android/gms/d/lb;)Lcom/google/android/gms/d/kn;]
Exception = [java.lang.IllegalArgumentException] (Can't find common super class of [com/google/android/gms/d/kn] (with 1 known super classes) and [java/lang/String] (with 2 known super classes))
Warning: Exception while processing task java.io.IOException: java.lang.IllegalArgumentException: Can't find common super class of [com/google/android/gms/d/kn] (with 1 known super classes) and [java/lang/String] (with 2 known super classes)
Here is my Proguard Configurations
-keep public class com.google.android.gms.* { public *; }
-dontwarn com.google.android.gms.**
-keep class com.facebook.ads.** { *; }
Here is the list of gradle dependencies of my project
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.google.firebase:firebase-perf:16.0.0'
implementation 'com.google.firebase:firebase-config:16.0.0'
implementation 'com.google.firebase:firebase-core:16.0.0'
implementation 'com.google.firebase:firebase-messaging:17.0.0'
implementation 'com.google.android.gms:play-services-analytics:16.0.0'
implementation 'com.google.android.gms:play-services-drive:15.0.1'
implementation 'com.google.android.gms:play-services-auth:15.0.1'
implementation 'com.startapp:inapp-sdk:3.8.4'
implementation 'com.facebook.android:audience-network-sdk:4.28.2'
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.7.1'
testImplementation 'org.powermock:powermock-mockito-release-full:1.4.9'
implementation('com.crashlytics.sdk.android:crashlytics:2.9.1#aar') {
transitive = true
}
}
Note Commenting the Facebook audience network dependency fixes the error. Unfortunately I cannot do it permanently from the project.
Please help me identifying the cause of an issue. Thanks in advance.
Finally I managed to fix the error. As I am not Proguard expert, I may be wrong but this is the workaround I see at the moment.
As I have mentioned in the question, Facebook Audience Network causes the problem with the release build and errors are associated with the GMS Play Service library. According to comment posted by #pedrofsn, Facebook Audience Network uses the Google Play Service Ads library.
I started looking into documentation for the error Can't find common super class of. It says that
A class in one of your program jars or library jars is referring to a
class or interface that is missing from the input. The warning lists
both the referencing class(es) and the missing referenced class(es).
There can be a few reasons, with their own solutions:
As it says the warning lists both the referencing class(es) and the missing referenced class(es), I decided to remove dontwarn just to see the warnings by the Proguard & updated my Proguard Configuration as below
-keep public class com.google.android.gms.* { public *; }
-keep class com.facebook.ads.** { *; }
I managed to see all the warnings by Proguard as the screenshot below.
As we can see from the screenshot, google ads library classes cannot find their referenced class com.google.android.gms.common.internal.zzac. My guess is that this class com.google.android.gms.common.internal.zzac should belong to the internal jar of the google ads dependency & that internal jar is probably missing.
So I have manually added the google ads dependency to my app level build.gradle as below
implementation 'com.google.android.gms:play-services-ads:15.0.1'
And I see I can compile the release build successfully.
I fixed downgrading 'com.google.firebase:firebase-messaging:17.0.0' to 'com.google.firebase:firebase-messaging:15.0.2'
For this to work, I had to uncomment:
buildTypes {
release {
//minifyEnabled true
//shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
and add the below to your proguard-rules.pro file:
-keep class com.google.android.gms.internal.** { *; }
-keep public class com.google.android.gms.* { public *; }
-dontwarn com.google.android.gms.**
although uncommenting minifyEnabled is not recommended since it removes dead/unused code
I have a problem after adding compile "com.google.firebase:firebase-firestore:11.4.2" to my build.
As soon as I add that, it also adds com.google.common among other things to my dex file, which is around 27k extra references, thus bursting through the 64k dex limit.
Does anyone know why that is or am I doing something wrong?
Try adding these lines to your build.gradle
android {
defaultConfig {
...
minSdkVersion 21
targetSdkVersion 26
multiDexEnabled true
}
...
}
This will enable multidex mode, which will allow you to exceed the 64k limit. (Read more here)
API below 21
If you're using an API level below 21, then you also need to add the support library
gradle.build:
dependencies {
compile 'com.android.support:multidex:1.0.1'
}
android.manafest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<application
android:name="android.support.multidex.MultiDexApplication" >
...
</application>
</manifest>
If you use a custom Application class, try using one the of the following
Solution 1
simply override the MultiDexApplication class
public class MyApplication extends MultiDexApplication { ... }
Solution 2
override attachBaseContext and install MultiDex using the install(Application) function
public class MyApplication extends SomeOtherApplication {
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
You're not doing anything wrong: the Android API for Cloud Firestore is just big. We'll be working on reducing SDK size on the road to GA.
Meanwhile, you need to enable multidex to build if your application is nontrivial.
We actually use very little of com.google.common, so you may be able to say under the 64k method limit by proguarding your application too.
Updating to 11.6.0 fixes this issue
I want to implement 2 name spaces under Application in android Manifest file to implement the firebase offline capabilities but it rejects taking 2 name spaces in the manifest file, see:
I tried to extend multiDexApplication in the MiLibrary Class, see:
public class MiLibrary extends Application {
#Override
public void onCreate() {
super.onCreate();
if (!FirebaseApp.getApps(this).isEmpty()) {
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
}
Picasso.Builder builder = new Picasso.Builder(this);
builder.downloader(new OkHttpDownloader(this, Integer.MAX_VALUE));
Picasso built = builder.build();
built.setIndicatorsEnabled(false);
built.setLoggingEnabled(true);
Picasso.setSingletonInstance(built);
}
but it gives me an error, see the stackTrace:
I've also tried searching here on stack-overflow and on Google but there are results or answers related to this, does anyone know how I can achieve this?
First of all in application tag you can define only single attribute for:-
android:name=".YourApplication"
Secondly, add the following dependency for okHttpClient:-
compile 'com.squareup.okhttp3:okhttp:3.2.0'
Your app's gradle file should look like this:-
defaultConfig {
...
minSdkVersion 14
targetSdkVersion //Yours
// Enabling multidex support.
multiDexEnabled true
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
}
Extend your application with MultiDexApplication class:-
public class MiLibrary extends MultiDexApplication { ... }
In your Manifest add name of your application as follows:-
<application
android:name=".MiLibrary"
...>
I'm using a FileProvider to get photos from the device. The implementation works just fine in debug builds (minifyEnabled false) but when I'm building the release build (minifyEnabled true) I get an error:
java.lang.RuntimeException: Unable to get provider android.support.v4.content.FileProvider:
java.lang.ClassNotFoundException: Didn't find class "android.support.v4.content.FileProvider"
on path: DexPathList[[zip file "/data/app/com.package.name-2/base.apk"],
nativeLibraryDirectories=[/data/app/om.package.name-2/lib/arm, /vendor/lib, /system/lib]]
So I guess this has someting to do with the proguard setup
I have
compile 'com.android.support:support-v13:23.1.1'
which is a superset of v4 in my gradle file and
minSdkVersion 21
targetSdkVersion 23
and
-keep class android.support.v4.app.** { *; }
-keep class android.support.v4.content.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep interface android.support.v4.content.** { *; }
-keep class * extends android.content.ContentProvider
in my proguard-rules.pro file
I have tested with both Android 5 and 6 and same thing happens.
Any suggestion would be usefull, thanks in advance.
The following worked for me:
In your module build.gradle file:
defaultConfig {
...
multiDexEnabled true
...
}
Then:
dependencies {
...
compile 'com.android.support:multidex:1.0.2'
...
}
And finally, ensure that your application class has one of the following:
A. If you do not extend your application class:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<application
android:name="android.support.multidex.MultiDexApplication" >
...
</application>
</manifest>
B. If you do extend your Application class and but can change the base class:
public class MyApplication extends MultiDexApplication { ... }
C. If you do extend your Application class and cannot change the base class:
public class MyApplication extends SomeOtherApplication {
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
For more info:
https://developer.android.com/studio/build/multidex.html#mdex-gradle
I was using androidx library and getting the same error. So, in AndroidManifest.xml, I changed this line:
android:name="android.support.v4.content.FileProvider"
to this:
android:name="androidx.core.content.FileProvider"
After a couple of hours of more googling around I've ended up updating gradle and google services to
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
classpath 'com.google.gms:google-services:1.5.0'
}
previously the version ware
classpath 'com.android.tools.build:gradle:1.3.0'
classpath 'com.google.gms:google-services:1.5.0-beta2'
I guess there needs to be something with the google-services library