Having an issue where the apk being generated by our Gradle build contains a bunch of unnecessary files inside a test/resources directory
Our application build gradle contains several local module dependencies which are built as android libraries.
I know there is packagingOptions field in Gradle but you can't exclude directories as far as I can tell. Excluding each file isn't an option. Anyway, I would like to know the root cause for this.
Application gradle build:
apply from: "${rootDir}/android_application.gradle"
dependencies {
compile project(':local-lib1')
//... etc
compile project(':local-libN')
testCompile libraries['junit']
}
android {
defaultConfig {
versionCode 1
versionName "1.0"
multiDexEnabled true
}
}
And android_application.gradle:
apply plugin: 'com.android.application'
android {
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
resources.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
}
compileSdkVersion android_sdk_version
buildToolsVersion android_build_tools_version
defaultConfig {
minSdkVersion android_min_sdk_version
targetSdkVersion android_target_sdk_version
}
buildTypes {
}
}
All modules are structured like so:
module
|
--AndroidManifest.xml
--build.gradle
--assets/
--res/
--src
|
-- main/
| |
| --java/
| --resources/
|
-- test/
|
--java/
--resources/
Why are test/resources being included in apk? How can I exclude them?
Edit (to show lib gradle):
Example lib gradle:
apply from: "${rootDir}/android_library.gradle"
dependencies {
compile 'com.android.support:multidex:1.0.0'
// ...etc external deps
// test deps
testCompile libraries['logback-classic']
testCompile libraries['junit']
testCompile libraries['mockito-core']
// etc...
}
android {
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
exclude 'META-INF/ASL2.0'
exclude 'META-INF/notice.txt'
exclude 'META-INF/license.txt'
}
}
android_library gradle:
apply plugin: 'android-library'
android {
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
resources.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
}
compileSdkVersion android_sdk_version
buildToolsVersion android_build_tools_version
defaultConfig {
minSdkVersion android_min_sdk_version
targetSdkVersion android_target_sdk_version
}
buildTypes {
release {
}
}
}
I am building with gradlew.bat -x test build
The test/resources included in the apk contains all the files in the corresponding test/resources for each lib. The size of directory (uncompressed) is 10mb so adds unreasonable amount to size of overall apk.
Try the resource shrinking. As per Google Documentation: "The Gradle build system for Android supports
resource shrinking": the automatic removal of resources that are
unused, at build time, in the packaged app. In addition to removing
resources in your project that are not actually needed at runtime,
this also removes resources from libraries you are depending on if they are not actually needed by your application
android {
...
buildTypes {
test {
minifyEnabled true
shrinkResources true
...
}
}
}
Think I've solved the issue.
I had in app build.gradle and each library build.gradle:
android {
sourceSets {
main {
resources.srcDirs = ['src']
}
}
}
Changed to
android {
sourceSets {
main {
resources.srcDirs = ['src/main']
}
}
}
I guess gradle was taking every resources dir under src/ and merging them into one - http://tools.android.com/tech-docs/new-build-system/resource-merging
Related
I have a AndroidStudioSupport Project which has modules.
1. module 1 takes care of Android UI part
2. module 2 is a library project which generates .aar file
3. module 3 is a java project which generates jar file
Now I want to build the project in a way that
1. First build jar project
2. Then copy generated jar into libs of library project as a dependency
3. Then build aar file
4. Then copy generated aar into libs of UI project as a dependency
5. Finally generate .apk file
Please suggest me what changes do I have to do in my gradle files
jar project gradle file
apply plugin: 'java'
sourceSets {
main.java.srcDirs = ['src/main/java']
main.resources.srcDirs = ['src/main/java']
test.java.srcDirs = ['tests/java']
test.resources.srcDirs = ['tests/resources']
}
jar {
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it)}
}
}
library project gradle file
apply plugin: 'com.android.library'
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile project(':java_project')
}
task copyToLib(type: Copy) {
from configurations.compile
into 'libs'
}
build.dependsOn(copyToLib)
android {
publishNonDefault true
compileSdkVersion 21
buildToolsVersion '23.0.2'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src/main/java']
resources.srcDirs = ['src/main/java']
aidl.srcDirs = ['src/main/java']
renderscript.srcDirs = ['src/main/java']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
// Move the tests to tests/java, tests/res, etc...
instrumentTest.setRoot('test')
}
buildTypes {
debug {
jniDebuggable true
}
}
}
This current implementation doesn't include jar from my java project
I have a dummy project, which I succeed to compile through buildship plugin in eclipse IDE.
This is my local.properties file:
sdk.dir=C:/Asta/altro/adt-bundle/sdk
This is settings.gradle file
rootProject.name = 'testgradle'
This is my build.gradle file
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
}
}
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.example.testgradle"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
}
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
}
lintOptions {
abortOnError false
}
}
sourceCompatibility = 1.6
targetCompatibility = 1.6
repositories {
jcenter()
flatDir {
dirs 'libs'
}
}
dependencies {
compile 'org.slf4j:slf4j-api:1.7.21'
compile 'com.android.support:appcompat-v7:23.4.0'
testCompile 'junit:junit:4.12'
}
task wrapper(type: Wrapper) {
gradleVersion = '2.10'
}
Despite I got the apk fully compiled, eclipse is not integrated: still seeing missing libraries and giving more than a 100 errors! All the libs are perfectly managed by gradle in \build\intermediates\ and assembled into apk, but the eclipse IDE is not "live". I would like to use gradle to download and explode the libraries and then to inform eclipse and let it to make the apk with its own builder.
Buildship can be used only to run Android tasks (assembleDebug).
During the build process it will load dependencies and tell if there're some errors.
To load dependencies into Java classpath, to see errors in Eclipse and resolve imports you can either manually add .jar files to your Java Build Path or use this Gradle plugin: https://github.com/greensopinion/gradle-android-eclipse.
It generates classpath for Eclipse project and you just import it into the IDE.
To run Gradle tasks you can create a Run configuration (named "Gradle Project") and put there your task and Working directory.
my app exceeding 64k methods so iam supposed to implement Multidex ,
initially i had problem as "local path doesnt exist" i fixed that problem ,now gradle generated classes1.dex and classes2.dex ,
but not working in lower than lollipop..it was working fine in lollipop since it has a native support .error says that "<1st activity> is not present in dex path"
after seeing some tutorials they said that have to do a change in 1.gradle 2.application class 3.manifest
i dont have much knowledge about application class ..kindly guide me thanks
note:this is an imported project from eclipse .
kindly check build.gradle file
apply plugin: 'com.android.application'
android {
defaultConfig {
compileSdkVersion 23
buildToolsVersion '23.0.1'
minSdkVersion 15 //lower than 14 doesn't support multidex
targetSdkVersion 23
}
dexOptions {
jumboMode = true
preDexLibraries = false
javaMaxHeapSize "2048M"
}
afterEvaluate {
tasks.matching {
it.name.startsWith('dex')
}.each { dx ->
if (dx.additionalParameters == null) {
dx.additionalParameters = ['--multi-dex']
} else {
dx.additionalParameters += '--multi-dex'
}
}
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
// Move the tests to tests/java, tests/res, etc...
instrumentTest.setRoot('tests')
// Move the build types to build-types/<type>
// For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
// This moves them out of them default location under src/<type>/... which would
// conflict with src/ being used by the main source set.
// Adding new build types or product flavors should be accompanied
// by a similar customization.
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
productFlavors {
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:multidex:1.0.1'
}
You followed a tutorial that shows how you could add multi-dex support manually before Android gradle plugin had support for it. Since v0.14.0, all you need to do is to add:
android {
defaultConfig {
...
multiDexEnabled true
}
And you can choose one of three options to call the MultiDex code. From MultiDexApplication documentation:
Minimal MultiDex capable application.
To use the legacy multidex library there is 3 possibilities:
- Declare this class as the application in your AndroidManifest.xml.
- Have your Application extends this class.
- Have your Application override attachBaseContext starting with
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
Don't forget to remove the afterEvaluate block from your build script.
Make sure you've read the official documentation.
I have an issue to import mupdf library into my android application. The problem is that the program was running well last week, and I probably changed something in the code that don't load mupdf anymore. If I try to load a pdf file, I have a message with "-my application- has stopped". Here is the logcat error message :
2530-2530/com.efc.efcredader E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.ExceptionInInitializerError
at com.artifex.mupdfdemo.MuPDFActivity.openFile(MuPDFActivity.java:944)
at com.artifex.mupdfdemo.MuPDFActivity.onCreate(MuPDFActivity.java:710)
[...]
Caused by: java.lang.UnsatisfiedLinkError: Couldn't load mupdf: findLibrary returned null
at java.lang.Runtime.loadLibrary(Runtime.java:365)
at java.lang.System.loadLibrary(System.java:535)
at com.artifex.mupdfdemo.MuPDFCore.<clinit>(MuPDFCore.java:16)
[...]
I call the libmupdf.so like that :
static {
System.loadLibrary("mupdf");
}
I've followed a lot a tutorials about how to build mupdf as a library and import it but no one works well (at least for me). So I suppose (and I hope), I'm doing something wrong during the manipulation.
After I imported the "Android" module from mupdf, the folder is like that :
>android
>manifests
Android.Manifest.xml
>java
>com.artifex.mupdfdemo
All java files
>res
>animator
Xml files
>drawable
Xml files
>layout
Xml files
>values
Xml files
>c
Android.mk
Application.mk
Core.mk
libmupdf.so
mupdf.c
ThirdParty.mk
Even if I try to compile it alone, I have some errors too :
make.exe:***No rule to make target ...
and
Execution failed for task ':android:compileDebugNdk'.
com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'C:\android-ndk-r10d\ndk-build.cmd'' finished with non-zero exit value 2
Here is the project's build.gradle
apply plugin: 'android'
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile project(':appcompat_v7')
compile project(':android-support-v4-preferencefragment-master')
compile project(':android-support-v7-gridlayout')
}
android {
compileSdkVersion 19
buildToolsVersion "19.1"
compileOptions.encoding = 'ISO-8859-1'
packagingOptions {
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LICENSE.txt'
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
}
android's build.gradle :
apply plugin: 'com.android.library'
android {
compileSdkVersion 16
buildToolsVersion "19.1.0"
defaultConfig {
//applicationId "com.artifex.mupdfdemo"
minSdkVersion 8
targetSdkVersion 16
ndk {
moduleName "mupdf"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
local.properties
sdk.dir=C\:\\Android\\SDK
ndk.dir=C\:\\android-ndk-r10d
I'm using Android Studio and the SDK is up to date.
I really don't know how to solve that right now, I would be glad If you have any advice that can help me. If you need any other details or files to add, just ask.
Thank you.
My solution is:
I'm having the .so files in lib/armeabi and lib/armeabi-v7a, and in the build.gradle I added jniLibs.srcDirs = ['libs'] to the existing sourcesets. Hope that is helping you!
I am currently working on setting up a multi-module project, with the following structure:
Project Root
|- app/
|- src/
|- build.gradle
|- lib
|- src/
|- build.gradle
|- build.gradle
|- gradle.properties
|- settings.gradle
While the library module builds as expected, I get the following build error for the app module:
A problem was found with the configuration of task ':app:prepareProjectRootLib10Library'.
> File 'C:\projects\Project Root\lib\build\outputs\aar\lib-1.0.aar' specified for property 'bundle' does not exist.
As far as my build script goes, I do not think I am doing anything wrong with my build scripts. At the same time, when I look for the generate .aar for my library project, I instead find a lib-1.0-SNAPSHOT.aar file instead, which explains the problem. While manually renaming that file to match what the build script expects fixes the issue, I need a solution that does require manual work. Is there a way to modify the build script such that the application module can get the library project files it needs?
If it helps, below is app/build.gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 20
buildToolsVersion '20.0.0'
defaultConfig {
minSdkVersion 16
targetSdkVersion 20
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
sourceSets {
main {
java.srcDirs = ['src/main/java']
resources.srcDirs = ['src/main/resources']
res.srcDirs = ['src/res']
assets.srcDirs = ['src/assets']
}
androidTest {
java.srcDirs = ['src/androidTest/java']
resources.srcDirs = ['src/androidTest/resources']
res.srcDirs = ['src/res']
assets.srcDirs = ['src/assets']
}
}
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
}
}
dependencies {
compile project(':lib')
compile 'com.android.support:support-v4:20.0.0'
}
And this is lib/build.gradle:
apply plugin: 'com.android.library'
android {
compileSdkVersion 20
buildToolsVersion '20.0.0'
defaultConfig {
minSdkVersion 16
targetSdkVersion 20
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
sourceSets {
main {
java.srcDirs = ['src/main/java']
resources.srcDirs = ['src/main/resources']
res.srcDirs = ['src/res']
assets.srcDirs = ['src/assets']
}
androidTest {
java.srcDirs = ['src/androidTest/java']
resources.srcDirs = ['src/androidTest/resources']
res.srcDirs = ['src/res']
assets.srcDirs = ['src/assets']
}
}
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
}
}
dependencies {
compile 'com.android.support:support-v4:20.0.0'
}