We have multiple projects, depending on a many Android lib modules.
To avoid duplicated xml tags in the apps manifests, we put the relevant receivers, services and activities in their respective modules.
Till today, we used:
Android Studio: 2.2.1
gradle: 2.1.3
buildToolsVersion: 23.0.3
Today we've updated to:
Android Studio: 2.3
gradle: 2.3.0
buildToolsVersion: 25.0.0
Up until this update, everything worked just fine and the manifests were merged, we had conflicts and we fixed them. As of the update we've done, the manifests will not merge, at all!!
--- Update 1 ---
We've used the Merged Manifest view, and saw that it just doesn't include the manifests in the merge, the only thing it does merge from the modules manifest is the permissions, so for example, if I add a new permission to a modules manifest it would ONLY merge it and not the rest of the elements!
I guarantee there are a lot of stuff to merge!
--- Update 2 ---
It seems that everything outside the application tag it merges into the main manifest, and everything within the application tag, it doesn't.
--- Update 3 ---
Module that doesn't merge:
Gradle:
apply plugin: 'com.android.library'
android {
compileSdkVersion 23
buildToolsVersion '25.0.0'
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
jniDebuggable true
}
}
}
dependencies {
compile project(path: ':android-infra')
compile 'com.google.android.gms:play-services-gcm:9.0.0'
compile project(path: ':engine-core-server')
compile project(path: ':engine-core-aneeda')
}
Manifest:
<manifest package="com.sensiya.voip.managers.gcm"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="com.google.android.c2dm.permission.KAKI"/>
<application
tools:node="replace">
<service
android:enabled="true"
android:name="com.sensiya.voip.managers.gcm.GcmIntentService"/>
<receiver android:name="com.sensiya.voip.managers.gcm.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
<category android:name="com.iamplus.onenumber.device"/>
</intent-filter>
</receiver>
</application>
</manifest>
Module that will merge:
Gradle:
apply plugin: 'com.android.library'
android {
compileSdkVersion 23
buildToolsVersion '25.0.0'
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
jniDebuggable true
}
}
}
dependencies {
compile project(path: ':android-infra')
compile 'com.sensiya:sense-services-client:1.24.2#aar'
compile project(path: ':engine-core-server')
compile project(path: ':engine-core-aneeda')
}
Manifest:
<manifest package="com.iamplus.android.senseServices"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
tools:node="replace">
<service
android:name="com.iamplus.senseServices.ContextualEventService"
android:enabled="true"/>
<service
android:name="com.iamplus.senseServices.Serv"
android:enabled="true"/>
<service
android:name="com.iamplus.senseServices.Serv1"
android:enabled="true"/>
</application>
</manifest>
Any suggestions?
It could be many things.Since you didn't provide code, I will guess you are using default merge behavior. For more information, see: Merge conflict heuristics
You can use Merged Manifest view to preview the results of your merged manifest and find conflict errors.
In general, merge by default should work. Then just use Merged Manifest view to see how & where you lost values during merging. Using Merge rule markers would help you to manage merge by assigning rules markers.
If there is no merge at all. so it's probably a dependency issue between modules.
Note that dependency order plays a crucial role with modules which have the same priority level, such as libraries.
--- Update 5.April.2017 ---
Here are some useful tips:
Try to update and rebuild other libs as much as you can.
Remove all dependencies and then clean project, then add them again. and
check if you import them properly. that could be done by build the project without issues.
Note that since gradle 2.2.0 assets from modules won't be accessible
in app.
Check you manifest if merge process is not disabled exciplicitly by attribute:
tools:node=”remove" or tools:node="removeAll" or in gradle( see
this Disable Manifest Merger in Android Gradle Build)
Try to create a demo with a module and track merging. and then match
outputs to your projects. This will make it clear that is not
configuration issue but Android Studio 2.3 ( so then re-install fresh
version )
--- Update(2) 5.April.2017 ---
After you had added code, I could see that you are using Attribute
tools:node="replace"
Under application element in your modules (and probably in app's manifest too). I think that is the reason why you didn't get any manifest merged from imported modules merged to your app's manifest. See tools:node="replace" under Node markers.
Replace the lower-priority element completely. That is, if there is a
matching element in the lower-priority manifest, ignore it and use
this element exactly as it appears in this manifest.
That means both modules above will never get any thing merged with manifest from:
android-infra
com.sensiya:sense-services-client:1.24.2
engine-core-server
engine-core-aneeda
So get rid of that attribute and clean and rebuild modules. then rebuild whole project.
If you are getting manifest merge conflicts you have two options.
1) find all the manifest files included in your project including the ones in libraries that you have as dependencies, and ensure there are no conflicting configurations.
or 2) add some merge resolution rules to your Manifests to dictate how each conflict should be resolved.
There is a great page on that here with many details.
https://developer.android.com/studio/build/manifest-merge.html
From Android Studio
Build ---> Clean project
then
Build --> Make Project
This should help fix
I had a similar problem for Unity. I was able to solve it by going on the SDK Manager and removing the latest android api. Then I installed a slightly older api and it worked (API 21 or 22 I think)
What the SDK Manager looks like
I recently have same problem in my production code.
Having one libraries into app module exists also in other Gradle Dependency causes the duplicate entries.
We need to exclude such module or libraries from conflicted one.
For that we must know number of libraries used by a particular Gadle dependency.
Consider a case where I using "bolts-android-1.2.0.jar" in my app gradle.
In same gradle I m using facebookSDK as below.
compile('com.facebook.android:facebook-android-sdk:4.5.0')
So I have to exclude "bolts-android" as below
compile('com.facebook.android:facebook-android-sdk:4.5.0') {
exclude module: 'bolts-android'
}
So how to know that facebookSDK uses "bolts-android"
Here you can use plugin Android Method Count
Seems like the problem is from using tools:node="replace" in the application element. From the documentation:
...if there is a matching element in the lower-priority manifest, ignore it and use this element exactly as it appears in this manifest.
What you actually want to use is tools:node="merge" which is the default behavior.
Merge all attributes in this tag and all nested elements when there are no conflicts using the merge conflict heuristics. This is the default behavior for elements.
Related
I'm creating a new android project and decided to use the new AndroidX replacement for the support libraries, docs for which can be found here: https://developer.android.com/jetpack/androidx/migrate.
I followed the steps to the letter and after syncing gradle I have access to the androidx namespace and various classes contained within. However, when creating my application class I want to inherit from androidx.multidex.MultiDexApplication (which can be seen in the table in the link above). However, the entire multidex package doesn't exist.
Has anyone resolved this issue? Any pointers?
android.enableJetifier=true does not make the least sense, while being able to replace it.
you can simply add it as a dependency, without non-transparent mangling of name-spaces:
implementation "androidx.multidex:multidex:2.0.1"
If you are using androidx you should add MultiDexApplication(reference from androidx) to your manifest file.
<application
android:name="androidx.multidex.MultiDexApplication"
.....></application>
In addition to Martin Zeitler's answer, I had to add in my gradle build file:
defaultConfig {
...
multiDexEnabled true // Add this line
...
}
As well as the dependency
implementation "androidx.multidex:multidex:2.0.0"
As to why it happens, this userguide on Android Developers explains it very well.
build.gradle app module
android {
compileSdkVersion 22
buildToolsVersion "23.0.0"
defaultConfig {
minSdkVersion 14 //lower than 14 doesn't support multidex
targetSdkVersion 22
// Enabling multidex support.
multiDexEnabled true
}
}
dependencies {
implementation 'com.android.support:multidex:1.0.3'
}
Ok, figured it out!
Multidex library was never part of android support lib, it was additional library that had to be imported in gradle. So, I've now imported it in my dependencies block in my modules gradle file and set the following in my gradle.properties file:
# Jetifier automatically updates dependancy binaries
# To swap out support lib for androix
android.enableJetifier=true
Now, at compile time, the multidex dependency is swapped out for androidx implementation.
We are having problems in building our multidex App. We keep receiving different java.lang.NoClassDefFoundError erros during the application boot.
We noticed that they are very likely related to the multidex issues. As the required classes for booting the App must be present in the primary DEX file and they are not being included in the classes.dex. We performed the steps described in https://developer.android.com/studio/build/multidex.html#keep
but the classes we specify in the multidex-config.txt, or even in the multidex-config.pro are not being placed in the primary dex file (classes.dex).
Do you guys have experience using the multiDexKeepFile or the multiDexKeepProguard? Does it really work? Is there any trick to make it work and place the files in the classes.dex?
Try updating your gradle plugin. I've seen that in 2.2.0 the configuration is ignored entirely. When I updated to 2.3.3 it started respecting the rules I set.
Example:
classpath com.android.tools.build:gradle:2.3.3
And in my default config I have this set:
multiDexEnabled true
multiDexKeepProguard file('proguard.multidex.config')
Also you may have to do a clean build before the changes are reflected.
I have the same problem.And i still don't know why.
But i found another solution,and it works.
In your app module's build.gradle add dexOptions:
android {
dexOptions {
additionalParameters = ['--multi-dex',
'--set-max-idx-number=60000',
'--main-dex-list='+projectDir+'/your_multidexconfig.txt',
'--minimal-main-dex'
]
}
}
You should check your minSdkVersion, if your minSdkVersion is >= 21, multiDexKeepProguard is not supported. Because the build tools has do the dex split by default.
More details:
https://developer.android.com/studio/build/multidex
Okay, so I can't develop nothing as my Android Studio decided to.
My all project is full of errors, unknown errors caused by Android Studio.
note: my files are correct, it is an other problem because even if I will import something from google codes it will have errors.
When I import a project everything's fine, but then after indexing and such things, all sudden everything is red and shouldn't be.
My errors for example are :
button1.setOnLongClickListener(new View.OnLongClickListener()
{
....
....
}
Well shouldn't be error but : cannot resolve symbol setOnLongClickListener
Another example:
button1=(Button) findViewById(R.id.button1);
I used this exact code for other button, seems right, I always using this line, it was fine until my Android Studio decided to give me some hard time, this line is full by errors and they are:
Unknown class: 'button1' , invalid method declaration; return type required, missing method body, or declare abstract
and there are like 20 errors that shouldn't be, things I tried:
deleting iml files , .idea folder - worked for a while but now it happened again and it doesn't fix it.
reinstalling android studio and then importing project.
upgrading android studio version to 1.3
restarting my pc.
importing project to an other pc, happened after a while.
Invalidate caches/ restart.
Changing module in project structure - I changed it back to how it was (it didn't help) and I think it caused the manifest error down..
My Module:app build.gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion '22.0.1'
defaultConfig {
applicationId "firstappdevelopments.david.reactiontime"
minSdkVersion 9
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.1'
}
Also I noticed now, my Manifest file as an error in android:name=".MainActivity" says it has no default structure. something like this. here is the full normal code:
<?xml version="1.0" encoding="utf-8"?>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
</manifest>
Please, if someone knows what is the problem or what can I else do, just say, and I am sorry about my English, thank you all.
What I've seen is my code is full of errors, but it still builds fine and deploys fine to the device.
To fix it:
click on FILE > INVALIDATE CACHES / RESTART
Then close the project
Re open the project
For me I upgraded my Kotlin Version from 1.4 to 1.5.0 and it is now working.
dependencies {
classpath 'com.android.tools.build:gradle:4.2.1'
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigationVersion"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.0"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
Afterwards I did a clean and a Rebuild and everything worked fine thereafter.
I have a library project FooLib which uses Google play service (location service). When I was using Eclipse, I have google-play-services-lib (also as a library project) in my workspace and I include it in FooLib, and everything is working fine. Now I am migrating to Android studio and I could not figure out a way to include Google play service in a library project. Here is what I have done so far:
Installed Google player service, Google Repository in the SDK manager. (I am using the latest Android studio 1.0.1)
2. Added compile 'com.google.android.gms:play-services:6.5.+' to the build.gradle file for FooLib under dependencies. Sync the gradle file. Here is my guild.gradle file
apply plugin: 'com.android.library'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
minSdkVersion 8
targetSdkVersion 21
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile 'com.google.android.gms:play-services:6.5.+'
compile files('libs/aws-android-sdk-1.5.0-core.jar')
}
The official doc (http://developer.android.com/google/play-services/setup.html) mentioned that I also need to add
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
to the manifest as a child of <application> tag. But in the manifest file for a library project, there is no <application> tag. I tried without the meta-data tag or adding a dummy <application> tag in the manifest and attached meta-data tag to it. Neither case works.
I tried both AndroidManifest files below
Or
I am still getting
Does anybody know how to add Google play service to a library project in Android studio? Much appreciated!
I just discovered something weird about Android studio: it has some configuration options in the build.gradle file that override what is specified in the AndroidManifest.xml file.
For instance, I had the following lines in build.gradle:
android {
compileSdkVersion 18
buildToolsVersion "18.1.1"
defaultConfig {
minSdkVersion 10
targetSdkVersion 10
}
...
}
which was overriding the corresponding tag in AndroidManifest.xml:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8"/>
I don't really like to have the same settings spread in two different files, so I am wondering if I can safely remove it either from build.gradle or AndroidManifest.xml and where it makes more sense to keep it.
Gradle overrides the manifest values, and I prefer to update the build.gradle file rather than the manifest. Probably this is the right way using Gradle. Gradle supports product flavours which can be controlled via an IDE and those product flavors can change many things in our Manifest like package name, version code, version name, target SDK and many other. Then by one click in Android Studio you can change many properties and generate another apk.
You can leave the manifest as it is and do all configuration in build.gradle. You can safely remove
<uses-sdk></uses-sdk>
from manifest as well as version codes.
From the Android docs:
Note: If your app defines the app version directly in the element, the version values in the Gradle build file will override the settings in the manifest. Additionally, defining these settings in the Gradle build files allows you to specify different values for different versions of your app. For greater flexibility and to avoid potential overwriting when the manifest is merged, you should remove these attributes from the element and define your version settings in the Gradle build files instead.
https://developer.android.com/studio/publish/versioning.html#appversioning