Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IntelliJ, Android and Gradle

I am trying to get my existing Android Project working with gradle and IntelliJ 12. Previously I had it working with maven but that didn't seem to be so flexible as gradle, and from what I think I got to know is that I need less subfolders.

My Android project is divided into a clean java library (:core) and the actual Application (:android). These two projects are both in my main project folder.

~-+MainProject
  |--+core
  |  L--build.gradle
  |--+android
  |  L--build.gradle
  |--build.gradle
  L--settings.gradle 

I think the ideal solution to get gradle work with this is to treat the (:core) and (:android) project as nested projects, meaning I can simply be with my cmd in MainProject source folder to start the gradle tasks.

However I came up with different problems:

  1. Gradle dependencies are only included in the core project
    • that means neither in the instrumentatetionTest nor in the main project files are any directories correctly set as source / test directories
    • IntelliJ doesn't resolve any classes that I added as dependencies in gradle (AndroidSDK, junit, mockito, those from the :core project)
      • tried to use the plugin 'idea' but either I used it wrong or it didn't solve the problem
  2. I get duplicate dependency Error for building the APK
    • must have something to do with junit:4.11 and mockito-core:1.9.5 that I added
    • what I tried:
      • deleting the dependencys -> build fails cause some classes of course could'nt be resolved
      • changing to junit:4.5+ as suggesed in some other thread -> no change at all

Here are the *.gradle configuartions

MainProject: -- settings.gradle

include ':core', ':android'

-- build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.6.+'
    }
}

subprojects {
    repositories {
        mavenLocal()
        maven { url "http://repo.maven.apache.org/maven2" }
    }
}

:core -- build.gradle

apply plugin: 'java'

dependencies {
    testCompile 'junit:junit:4.11'
    testCompile 'org.mockito:mockito-core:1.9.5'
}

:android

apply plugin: 'android'

repositories {
    mavenCentral()
}

dependencies {
     compile project(":core")

     compile 'com.google.android:android:4.1.1.4'

     instrumentTestCompile 'junit:junit:4.11'
     instrumentTestCompile 'org.mockito:mockito-core:1.9.5'
     instrumentTestCompile 'com.google.dexmaker:dexmaker:1.0'
     instrumentTestCompile 'com.google.dexmaker:dexmaker-mockito:1.0'

     instrumentTestCompile 'com.jayway.android.robotium:robotium-solo:3.6'
} 

/* ... androidSettings

I hope someone could help me with that

MFG Dornathal

like image 865
Dornathal Avatar asked Nov 21 '13 22:11

Dornathal


1 Answers

Alright, so you've got the right idea, but there are a few changes you still need.

Your root build.gradle file should be as follows:

subprojects {
    repositories {
        mavenCentral()
    }
}
  • You only need to include mavenLocal() if you are using a locally installed repo. Most people don't, and nothing in your project indicates that you need one.
  • mavenCentral() can be used to replace to maven URL you were using.
  • We only need to modify the buildscript for the android project, so we should localize that to the android project's build.gradle.

Your settings.gradle and your build.gradle for the core project are good.

Your build.gradle for the android project however, needs some changes:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.6.+'
    }
}

apply plugin: 'android'

dependencies {
    compile project(":core")

    instrumentTestCompile 'com.jayway.android.robotium:robotium-solo:3.6'
}
  • By including the android plugin, we link directly to the installed SDK. This means we no longer need to include the android dependency: compile 'com.google.android:android:4.1.1.4'.
  • We don't need to include junit. It's provided by the SDK, so we'll just use that. One thing to note is that the SDK only includes JUnit 3.
  • We don't need to include mockito and dexmaker unless we actually use it for the android tests. If it's only being used for the tests on the java library, we don't need it here.

To answer your questions:

  1. I'm not sure what you're asking here. It might help if you should your project structure including the directories in which you have files and such.
  2. Your hunch is correct. Hamcrest, which provides matchers for tests, made a breaking change to their API between versions 1.1 and 1.3. JUnit 4.11 has a dependency on Hamcrest 1.3. Mockito 1.9.5 however, depends on Hamcrest 1.1. So when both are included, the 1.3 overrides the 1.1 & Mockito no longer works. Reverting to JUnit 4.5 is also a problem. Junit 4.5 includes the Hamcrest 1.1 jar as a file rather than as a dependency in the POM. So this will cause issues when we have 2 versions of the same file. JUnit 4.10 is the way you want to go here. This has the dependency on Hamcrest 1.1 and includes it in the POM instead of as a file. Win win! I've had issues with this too, and the best way for me to figure it out was to just look at the POM files on Maven Central and see what they tell me.

One final note. Intellij 12 cannot handle Gradle Multi-project builds. You need to switch to Android Studio or Intellij 13 for that.

like image 68
MariusVolkhart Avatar answered Sep 21 '22 08:09

MariusVolkhart