Gradle: "apply plugin" at the top or at the bottom - android

Has the same effect add the "apply plugin" at the beginning or end of the file build.gradle in Android Studio projects?
For example to add the 'com.google.gms.google-services' plugin, Firebase official documentation recommends adding at the end, but I've seen other codes add it at the beginning.
I know the question seems irrelevant, but I'm developing a plugin for Android Studio to manage dependencies and have this doubt.
Thanks in advance

Gradle scripts are interpreted top to bottom so order can be important. Keep in mind that gradle has a configuration phase and an execution phase so sometimes order isn't important. It's common to apply your plugins at the top of the script since plugins often add extension objects and tasks to the gradle model which can then be configured lower down in the build script.
For example, you can't do the following because the test task is added by the java plugin:
test {
include 'org/foo/**'
}
apply plugin: 'java'

Related

Using Realm in a Cordova plugin for Android

I am experimenting with using Realm in place of SQLite in my hybrid Android/Cordova app which uses one custom - i.e. written by me - plugin. From the Realm documentation I have figured out that this has to be a two step process
Instructing Gradle to use the Realm plugin which I am doing via my plugin.xml file as io.realm:realm-gradle-plugin:6.0.2
"Applying the plugin" which according to the documentation involves issuing a apply plugin: 'realm-android' from the application levelbuild.gradle`file.
It is not clear to me how I do the latter. I tried putting the "apply plugin" statement in a build-extras.gradle file only to have Gradle complain
plugin with id 'realm-android' not found. Clearly, I am doing something wrong here. I'd be grateful to anyone who might be able to put me on the right path.
Sorry to destroy your delusions, but this assumption is just wrong:
Instructing Gradle to use the Realm plugin which I am doing via my plugin.xml file as io.realm:realm-gradle-plugin:6.0.2
I'd expect that to be required for the root project's build.gradle:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "io.realm:realm-gradle-plugin:6.0.2"
}
}
allprojects {
repositories {
jcenter()
}
}
As well as the module level build.gradle:
apply plugin: "realm-android"
...
dependencies {
// only this one line can be added through plugin.xml
implementation "io.realm:realm-android-library:6.0.2"
}
However, I think that Cordova by default only supports adding Java dependencies through plugin.xml, but no Gradle plugins - therefore you'd likely need to patch both build.gradle on demand, with a script similar to patchAndroidGradle.js, hooked into before_plugin_install. This obviously would then also need to be un-patched again, upon before_plugin_uninstall.
#MartinZeitler's answer is what put me on the right track here. For a Cordova project here is what you need to do:
Step 1
Open the platoforms/android/app/build.gradle file and in the dependencies{..} section add classpath "io.realm:realm-gradle-plugin:6.0.2".
Step 2
Now open the platforms\android\build-extras.gradle file - this is not created by default in Cordova so you might have to create a new one - and enter the following text
ext.postBuildExtras = {apply plugin: 'realm-android'}
Save the two files and perform a full rebuild of your project.
A few words of explanation are in order here. The mistake I had made was thinking that what was being supplied by Realm was a Java library. Not true. What you do in Realm is to model your data in the form of subclassed RealmObjects. Typically you will have multiple sub-classes of this type to fully define your data model. These sub-classes with their annotations are in effect instructions to Realm where you tell it how you are going to manage your data. As noted in the Realm docs
An annotation processor will create a proxy class for your RealmObject subclass.
The plugin you are incorporating into your project here is a Gradle plugin which extends the capabilities of Gradle. In this instance it is allowing the Realm annotation processor to examine your data model classes and create its own proxy classes. You can read up on how Gradle uses plugins here.
Add at the bottom :
apply plugin: 'realm-android' in the file build.gradle which is under the app folder of your project

A dependent feature was defined but no package ID was set. You are probably missing a feature dependency in the base feature

I am following one of the Google Codelabs for making an Instant App.
And I was trying to create topeka-ui (A UI feature module for Instant Apps).
When I try to run one of the instant app module it says :
A dependent feature was defined but no package ID was set.
You are probably missing a feature dependency in the base feature.
I had an issue in that I had an Android app and an Android Library, but I had used the wrong plugin by mistake.
For an app:
plugins {
id "com.android.application"
id "kotlin-android"
}
For a library:
plugins {
id "com.android.library"
id "kotlin-android"
}
Since this is the only stackoverflow question for "A dependent feature was defined but no package ID was set. You are probably missing a feature dependency in the base feature." I will answer what my issue was here rather than create a new question. I had a module that was giving me this error and couldn't figure out the problem. In the dependent module's build.gradle file, I had:
apply plugin: 'com.android.feature'
It should have been:
apply plugin: 'com.android.library'
I just ran through the codelab on AS 3.0 beta 2 without issues (*note). After what point in the codelab did your issue appear?
You might’ve missed a step. Double check that your base module’s build.gradle has:
dependencies {
...
application project(":topekaapk")
feature project(":topekaui")
}
Leaving out feature project(":topekaui") can cause this error:
Error:com.android.builder.internal.aapt.AaptException: A dependent
feature was defined but no package ID was set. You are probably
missing a feature dependency in the base feature.
Note: because data-binding has been disabled for non-base modules (https://issuetracker.google.com/63814741), there requires some additional steps in the multi-feature step-7 to get around it (ie. getting rid of the DataBindingUtil).
I did it in build.gradle(...mylibrary), fixed it and it worked:
plugins {
- id 'com.android.application'
+ id 'com.android.library'}
defaultConfig {
- applicationId "com.example.mylibrary"
minSdk 21
targetSdk 32}
I had this issue in my Dynamic Feature Module when I forgot to add a reference to it in the base module's android.dynamicFeatures = [":module_name"] array
Base from basic instant app project structure,
When you build your instant app, this module takes all of the features and creates Instant App APKs. It does not hold any code or resources; it contains only a build.gradle file and has the com.android.instantapp plugin applied to it. Here's an example:
apply plugin: 'com.android.instantapp'
...
dependencies {
implementation project(':base')
// if there additional features, they go here
implementation project(':feature1')
}
Furthermore, note that
The base feature module's build configuration file needs to apply the com.android.feature gradle plugin. The build.gradle file does not contain any instant app specific modifications.
With this and in line with your encountered error, you may want to check your base feature module's build configuration file. Lastly, make sure that you also sync your project with gradle files.
See Android Instant Apps documentation for more information.
With the following gradle pugin
classpath 'com.android.tools.build:gradle:3.5.1'
In my case, after adding to app's build.gradle
android{
dataBinding {
enabled = true
}
}
I got the posted error, then doing the following
Android studio -> invalidate cache and restart
Issue got fixed!
Not Fixed Yet?
Probably there is a conflicting dependency residing in build.gradle,
like the older and current version of the same library
This solution will work 100%
Step 1) Open gradle.properties
Step 2) Add android.enableJetifier=true to the file
Done!
See The Screen Shot:
You might have added dependent module as a application, it should be added as a library.
Check build.gradle file of module and
Replace
plugins {
id 'com.android.application'
to
plugins {
id 'com.android.library'
also remove applicationId from build.gradle's of inner module if its added in defaultConfig block

Why do we need to apply google-services plugin AT THE BOTTOM for Firebase SDK?

EDITED
As #doug-stevenson tells us in his answer, the Firebase dependency declaration does not have to be at the bottom of build.gradle anymore.
On the Firebase SDK setup page, it says,
apply plugin: 'com.android.application'
android {
// ...
}
dependencies {
// ...
compile 'com.google.firebase:firebase-core:9.0.2'
}
// ADD THIS AT THE BOTTOM
apply plugin: 'com.google.gms.google-services'
Why is that? Does the ordering matter?
UPDATE: With the latest version of the play services plugin, it is no longer necessary to apply it at the bottom of build.gradle.
It has to do with the way the plugin helps to manage dependencies, and the order of events that Gradle uses to build the project.
The plugin will actually add a dependency on firebase-core if it's not present in your project. It will also check the version of Firebase and Play Services dependencies. However, in order for it to do all this without conflict with other plugins, the Google Services plugin has to run against a project after the project dependencies are already defined. So, applying the plugin after the dependencies block (typically at the bottom of the file) makes all this possible.
The important thing to know is that some projects may experience a version conflict problem if the plugin is at the top. You will avoid these problems by adding it to the bottom.

integrating GCM and gcm_defaultSenderId is not resolved

I am integrating GCM into my app, what i did was i have made the configuration file google-services.json and placed it inside the app folder (i am using Android Studio) the resource file is also imported and I am also including the plugin in my build.gradle of application like this
apply plugin: 'com.google.gms.google-services'
the problem is that it is still not resolved. I want to know what is wrong?
I have searched about it and i find this, i have used my project number now there is no error coming up. Is it right way to do? Someone please explain
Take a look at the gradle files of the official google example: https://github.com/googlesamples/google-services/tree/master/android/gcm
You will see you need to do two things:
add
classpath 'com.google.gms:google-services:2.0.0-beta6'
to project gradle build file and
apply plugin: 'com.google.gms.google-services'
at the bottom of module app gradle build file.

Java-Module using Android API with Gradle

I am currently migrating an Android project from classic IntelliJ IDEA format to Gradle. In my project, there are modules that are using the Android SDK without being Android modules. They are plain Java modules that use the Android SDK instead of a JDK.
How can I achieve that with Gradle?
The approach I can think of is to apply plugin: 'java' and somehow configure the Android SDK as the used JDK or as a dependency. But I don't know how to do it exactly...
I have just revisited Eugen's first hint and "suddenly" it works.
So, basically you need to apply the Java plugin and add Android as a provided dependency.
apply plugin: 'java'
configurations {
provided
}
dependencies {
provided 'com.google.android:android:2.2.1'
}
#Eugen: Maybe you'd like to repost this to receive your credits.

Categories

Resources