I followed the Android Java 8 Features manual. It works well for Android application project. But when I try to use it with Android library project I get
Error:Library projects cannot enable Jack. Jack is enabled in default config.
Partial solution:
I enabled lamdba expression with Gradle Retrolambda Plugin.
I had the same issue and tried different approaches. It now works for me without using retrolambda (which produced some weird error during runtime). Also Jack is not active for the same reason you already mentioned.
There is an interesting bug post at google.com about this topic: https://code.google.com/p/android/issues/detail?id=211386
Here is my build.gradle script, I used the workaround from the bug post to fix the "MethodType not found" exception during compilation.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.2'
}
}
apply plugin: 'com.android.library'
repositories {
mavenCentral()
}
// Java8 not fully supported in library projects yet, https://code.google.com/p/android/issues/detail?id=211386
// this is a temporary workaround to get at least lambdas compiling
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xbootclasspath/a:" + System.properties.get("java.home") + "/lib/rt.jar"
}
}
android {
compileSdkVersion 24
buildToolsVersion "24"
defaultConfig {
minSdkVersion 10
targetSdkVersion 24
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
This sure has been a long ride. I tried all possible combinations of the gradle plugin, the experimental gradle plugin + retrolambda + Jack etc, but with no luck. Until now. From Android Studio 3.0 Preview 1 or later (and, consequently, the Android Gradle plugin 3.0.0-alpha1 or later), the Jack toolchain is deprecated and replaced by some new bytecode transformation - sugaring, used in conjunction with the standard javac compiler.
With this setup I've personally (finally!!!) been successful in using Java 8 features such as lambdas in a library project.
This page has all the techy info as well as migration help etc: https://developer.android.com/studio/write/java8-support.html
Related
I have an Android application that we have been building in Eclipse for years, and I am finally porting it to Android Studio (I am new to Android Studio and Gradle, so forgive my ignorance). I have successfully ported it and the app is up and running in Android Studio, but now need to overcome a couple more obstacles:
I want to upgrade deprecated methods and also move to the latest versions of Support Library, Google Services and GSon (I guess I can live without upgrading GSon if need be).
To complicate matters, we have an Ant based build which takes the source code and generates numerous white label instances of application, with some pretty complex replacements. I plan on keeping that - I don't want to Gradle that just yet (and not sure Gradle could handle it?).
So, first it looks like my Gradle generated by the port has dependencies as follows:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.mydomain.myapp"
minSdkVersion 14
targetSdkVersion 23
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile 'com.android.support:support-v4:23.4.0'
compile 'com.google.code.gson:gson:2.2.4'
compile 'com.google.android.gms:play-services:+'
[....other dependencies that don't matter here....]
}
My question is : do I still need to have the upgraded versions of these libs here or is this done via a Gradle addition for running out Android Studio? And if not by lib dependencies as listed, how can I have the Ant build pick these upgrades once I make them? I do have a further complexity in that I think the generated source code structure is different than Eclipse, but I think I can adjust the Ant build accordingly.
I have read these, and while helpful really don't quite answer my question:
Android white labeling
and
Android App White Labeling
Thanks!
UPDATE
So after a LOT of playing around I finally have upgraded modules and libraries and it apparently (I need to do a lot of testing) is working. Not sure if this will save anyone anytime in the future, but the key seems to be:
Match the compileSdkVersion and buildToolsVersion versions.
Match the com.android.support:support and compile and tools versions, as closely as possible.
For the Support lib, choose the version just below your minSDK version (in my case it is 14, so I chose v13). I might have it wrong there but that is what got it working for me.
Be careful in which modules and which version of the modules you bring in, and that they are compatible. The tool did a decent job of warning, but if you are bring in the entire play services I would recommend pulling in the pieces since that was where my incompatibilities were coming from. Here is what it looks like now:
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion '25.0.2'
defaultConfig {
applicationId "com.mydomain.myapp"
minSdkVersion 14
targetSdkVersion 23
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile 'com.google.android.gms:play-services-maps:11.0.4'
compile 'com.android.support:support-v13:25.3.1'
compile 'com.google.code.gson:gson:2.7'
}
For anyone who finds the whole support library to be confusing and a mess (why would anyone think that?) this blog was very helpful:
http://martiancraft.com/blog/2015/06/android-support-library/
Thanks also to Gabriele Mariotti for pointing me in the right direction. I will address the White Labeling conversion to Gradle in another question. Please chime in if I have this all incorrect...I will be the first to admit this is all very confusing!
My question is : do I still need to have the upgraded versions of these libs here or is this done via a Gradle addition for running out Android Studio?
compile 'com.android.support:support-v4:23.4.0'
compile 'com.google.android.gms:play-services:+'
Using the latest version is always a good idea
You should avoid using the the wildcard + in your dependencies, because in this way you are not able to replicate the same build in different time (because it changes in the time).
Use the same version of support libraries. The gms libraries have a dependencies with the support-v4 and you should use the same version.
it is not a good idea to have all gms modules (com.google.android.gms:play-services). You can add only the required modules.
And if not by lib dependencies as listed, how can I have the Ant build pick these upgrades once I make them?
It is not so simple. In my opinion you should convert your ant script in gradle. It would be easier.
When I enable the Jack compiler in Android Studio 2.2 the Dagger 2 component is not generated. Can Dagger 2 be used with Jack? If so, how would I go about configuring my application?
From my application's build.gradle:
jackOptions {
enabled true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
I sunk like 2 days into figuring this out. So I'm circling back to posting the findings here in case it saves someone time:
This is caused by a bug in Jack that prevents classpaths from working properly. It has to do with Jack running "in-process" (in the same JVM as the gradle daemon). Setting android.defaultConfig.jackOptions.jackInProcess to false does get beyond the "Preconditions" error but it causes other problems (2 JVMs that hog system resources) & bugs that break the build in other (worse) ways.
For now, the best solution seems to be:
Wait for the 2.3 release of the Android gradle plugin, which already has the fix for this.
Downgrade Dagger to v2.2, in the meantime.
It's the highest version that seems to avoid the Guava conflict with Jack.
EDIT: update 1/14/2017:
I ran into several OTHER problems with Jack and got so tired of it that I switched to retrolambda and kicked myself for not doing this earlier! Right now, Jack simply seems to cause more problems than it solves. Just add the lines with a plus and delete the lines with a minus and you can return to Dagger 2.8 while waiting for Jack to get it's act together!
+plugins {
+ id "me.tatarka.retrolambda" version "3.4.0"
+}
apply plugin: 'com.android.application'
+apply plugin: 'me.tatarka.retrolambda'
- jackOptions {
- enabled true
- }
For even faster retrolambda builds, add org.gradle.jvmargs=-Xmx4608M to your gradle.properties file so that dexing can happen in-process. Now, I'm on Dagger 2.8 and my clean builds are only 12 seconds, GOOD RIDDANCE, JACK!
The documentation page on Jack and Jill has instructions specific to annotation processors "to be applied at compile time but not to be included in your APK", advising the use of the annotationProcessor dependency scope. The example coincidentally mentions Dagger 2:
dependencies {
compile 'com.google.dagger:dagger:2.0'
annotationProcessor 'com.google.dagger:dagger-compiler:2.0'
}
Jack is now deprecated, see this post.
You have to upgrade your Android Studio to 3.0 preview 1, to be able to use Java 8.
If you can't upgrade it (conflict with other lib), or you want to wait for a release version, you can try this workaround solution :
Add the retrolamba lib, follow instructions here.
There are similar questions on the site, but most of them are from before Android Studio 2.1 and apparently that seems to have fixed it for everyone else except me.
I'm using Android Studio 2.1.1, JDK 1.8, NDK 1.2 rc1, gradle-experimental 0.7.0 alpha4 plugin, but I'm still having problems with Android Studio refusing to recognise any C library functions like stdio.h, jni.h, and so forth.
The problem is that header declarations like #include <stdio.h> all have the header's name in the error colours, and when I mouse over, the only explanation it offers is "cannot find stdio.h" for example. Then of course stuff like printf and system all show up in error colours
However, it runs perfectly fine with the C code. It's not like the greatest impediment, but I would love to actually use Android Studio's features rather than having to guess if I'm writing the correct code.
It turns out that in my app's build.gradle file, I had the NDK settings in the defaultConfig object instead of directly under android.ndk, which caused the issue. So do doublecheck your build.gradle files!
For reference, the fixed build.gradle file:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "meow"
}
buildTypes {
release {
minifyEnabled false
proguardFiles.add(file('proguard-rules.pro'))
}
}
ndk {
moduleName "mao"
ldLibs.add("log")
}
}
}
Looking at my build.gradle file (module:app, modified from the FragmentBasics example code)
- where is the android plugin ('com.android.application')?
- Where are the dependencies (e.g. "com.android.support:support-v4:22.2.0")?
- are these in Maven Central Repository or local?
I'm asking because I've had to meddle with the file names to get this project to build (e.g. the first version of com.android.support:support-v4 I tried would not build with my target sdk) - so I'm guessing future changes may break my build (correct?) and would like to get in early here. Also, are there different names for the android plugin (e.g. older names) in example code around the place? Has the name of the plugin changed over time (again, just wondering if future name changes here might break my build)?
Thanks
My build.gradle file for reference:
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "website.[...].FragmentBasics"
minSdkVersion 7
targetSdkVersion 22
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile 'com.android.support:support-v4:22.+'
compile "com.android.support:support-v4:22.2.0"
compile "com.android.support:appcompat-v7:22.2.0"
compile "com.android.support:support-annotations:22.2.0"
}
Android support library is not in maven center, it's in your android sdk.
Open Android SDK Manager, you can check it:
If you're using newer versions of Android Studio, Gradle will look for your dependencies in the JCenter repository rather than Maven Central. Basically JCenter is a superset of Maven Central, that encompasses many additional repositories and artifacts. Also, JCenter has a better performance than Maven Central.
If you don't update the versions of external dependencies, Gradle plugin and targetSdkVersion etc, your project will always be able to build.
I moved my android app over to Android Studio without switching to Gradle. Now I want to move to Gradle. The app compiles in Android Studio before switching to Gradle, but now that I have Gradle all set up, it won't compile the String Switch Statements or the diamond operators. The error I am getting is
Gradle: error: strings in switch are not supported in -source 1.6
(use -source 7 or higher to enable strings in switch)
I have made sure that I am running on JRE 7 by printing the
System.getProperty("java.version")
in a task. The output is
1.7.0_25
What confuses me most is the discrepancy between "-source 1.6" and "use -source 7". But I know that both of these are names for Java sdk's so maybe the titles are just being mixed up.
Is there a Gradle setting I need to set? or is this not possible in Gradle? If not it is confusing why it works without Gradle.
It should be noted that the without Gradle version of my project runs the default Android Studio build. I didn't write an ant script or maven script for building it. One of those may be the way it is being built, but I don't have any project specific files for them. Just the Android Studio .iml files.
UPDATE
I tried adding the following to the build.gradle android{} section
compileOptions {
sourceCompatibility = org.gradle.api.JavaVersion.VERSION_1_7
targetCompatibility = org.gradle.api.JavaVersion.VERSION_1_7
}
but the .class files failed to build and it weren't included in the apk. See the "Android Projects Need Libraries Compiled with Java 1.6" section on this post
You can upgrade an existing Android app/library module to Java 7 by adding the following in the android section of your build.gradle:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
For a Java (non-android) module, you should add the following to build.gradle just after apply plugin: 'java':
sourceCompatibility = 1.7
targetCompatibility = 1.7
For both types of modules, you will need to manually change the language level of your project in File -> Project Structure -> Project (or you can manually edit the config in .idea/misc.xml from JDK_1_6 to JDK_1_7).
You might also need to add the following to .idea/compiler.xml, in the <component name="CompilerConfiguration"> block (but see how you get on without it first):
<bytecodeTargetLevel target="1.7" />