In this post, we will see the ways of detecting memory leaks in Android and…
Solved – ZipException duplicate entry Android Studio
You might use a lot of jars in your libs directory, and there you may happen to duplicate the same jar or aar. Duplications may also occur when compiling remote libraries and you already have a local copy of the same in your libs directory.
For example, if you are having the following files in your libs directory,
1 2 3 4 5 |
gson-2.1.jar guava-18.0.jar jackson-core-2.1.3.jar java-api-core-2.9.0.jar java-api-core-2.9.3.jar |
You are clearly duplicating java-api-core since it is included twice, one with the version 2.10.1 and another with the version 2.10.5. As I already said in my previous post here, Gradle build is not so lenient in handling duplicate files, and you should avoid such duplications. You should clearly tell the build system which versions of libraries need to be included. The compiler can not choose the appropriate one and hence you have to manually do it.
The simple solution, in this case, is to remove the java-api-core-2.9.0.jar file from the libs directory, and the issue should be resolved.
But wait! So, what do you do when you can't find the duplicate files yourself!
Well, Straight to the point! Let us consider this example:
ZipException duplicate entry android/support/v4/internal/view/SupportMenu.class
To make it clear! First, we shall find the duplicate class.
- Search for this class file in Android Studio.
- Just hit Ctrl+N on Windows or CMD+O on Mac and type in “SupportMenu”.
- See which jar contains it ( Android Studio will show it in a popup ).
- In our case, the jar that contains the SupportMenu class is “android.support.v4”,
- Now all we need to do is to simply exclude it from all builds!
Add this Code to your app’s gradle:
1 2 3 4 5 |
android { configurations { all*.exclude module: 'android.support.v4' } } |
And we are done!
Most common encounters and their Solutions
Let us consider the following example,
1 2 3 4 |
dependencies { compile 'com.android.support:support-v4:19.+' compile 'com.android.support:appcompat-v7:19.+' } |
If the project uses two libraries like this, you should exclude support-v4 from the appcompat-v7 since appcompat v7 itself has support-v4 files, which eventually produces duplicate zip exception during execution time if used together.
In such case, add the following code to your app’s gradle to exclude support-v4 module from appcompat-v7
1 2 3 |
compile ('com.android.support:appcompat-v7:19.+') { exclude group: 'com.android.support', module:'support-v4' } |
If the error still exists, you should be having a local copy of the same in your libs directory. Go to app -> libs folder and check if there’s a stand-alone android-support-v4.jar file too. If then, just delete the jar file and do a clean, rebuild.
Few examples of exclude syntax
While excluding a remote library:
1 2 3 |
compile ('com.google.android.gms:play-services:7.0.0'){ exclude group: 'com.android.support', module:'support-v4' } |
While excluding a local library project:
1 2 3 |
compile (project(':android-support-v7-appcompat')){ exclude module: 'support-v4' } |
Some of the best practices
1. Don't Use compile fileTree
This is far the easiest method of including all your jar files in your libs folder. But while you are using a compile fileTree, it eventually hides the jar files from you. You won’t be aware of the files you are including, and so for a clear statement explicitly include the files in your dependencies block, and so it will be easier to find when you have duplicates.
2. Set application id in the build file
There are a lot of differences between applicationId and packageName. When it was Eclipse IDE, that was used to develop applications you simply specify the packageName in your AndroidManifest.xml and it was all that was needed.
The package name used in your source code to refer to your R class is the same package name in your AndroidManifest.xml. This is used to resolve any relative activity/service registrations.
In Android Studio, the unique id you give to your application is the applicationId in your Gradle build file. This is how the package name of your app known in the Google Play store too. Only when you don’t specify an applicationId in your build gradle file, the package name in your AndroidManifest.xml will be taken. Simply, Gradle overrides everything in the Manifest file.
For the consistency of Application, it is worth to set applicationId explicitly in your build configuration:
defaultConfig {
applicationId “com.example.myapp”
// …
}
There are few issues in not specify your applicationId in the Gradle build file. The applicationId may not get populated at once, and this could result in your app failing to install on the devices from the Google Play Store. This could end up with the disability of report tools to notify you about the crash reports and other analytics.
This Post Has 0 Comments