Error duplicate resources android studio

То, что Android считает, что при сопоставлении изображений в ваших макетах одно и то же:... Вопрос по теме: android, android-layout.

То, что Android считает, что при сопоставлении изображений в ваших макетах одно и то же:

E:AndroidLEDappsrcmainresdrawable-hdpilogin_bg.png
E:AndroidLEDappsrcmainresdrawable-hdpilogin_bg.9.png

login_bg.9.png image сообщает Android, что это изображение является 9-патч-изображением. В то время как другое изображение, login_bg.png, является обычным образом. Но с точки зрения ссылок на изображения они объявляются одинаковыми, как в следующих примерах.

Нормальное изображение:

<ImageView
    android:id="@+id/normalImage"
    android:background="@drawable/login_bg"/>

Изображение Nine-patch:

<ImageView
    android:id="@+id/ninePatchImage"
    android:background="@drawable/login_bg"/>

Примечание. Нет никакой разницы в ссылках на изображения из вашего каталога /res/drawables вашего проекта Android.

См. здесь для получения дополнительной информации об изображении с девятью патчами, или для правильного термина для него доступно девять патчей. Для справки, 9-патч-чертежи должны быть объявлены как <name>.9.png, как в login_bg.9.png.

  • Review the documentation: https://facebook.github.io/react-native
  • Search for existing issues: https://github.com/facebook/react-native/issues
  • Use the latest React Native release: https://github.com/facebook/react-native/releases

Environment

React Native Environment Info:

System:
  OS: macOS 10.14
  CPU: (4) x64 Intel(R) Core(TM) i5-7267U CPU @ 3.10GHz
  Memory: 103.10 MB / 8.00 GB
  Shell: 3.2.57 - /bin/bash
Binaries:
  Node: 8.12.0 - /usr/local/bin/node
  Yarn: 1.0.1 - /usr/local/bin/yarn
  npm: 6.4.1 - /usr/local/bin/npm
  Watchman: 4.7.0 - /usr/local/bin/watchman
SDKs:
  iOS SDK:
    Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1
  Android SDK:
    API Levels: 16, 17, 19, 21, 23, 24, 25, 26, 27, 28
    Build Tools: 19.1.0, 20.0.0, 23.0.1, 23.0.2, 23.0.3, 25.0.0, 25.0.1, 25.0.2, 25.0.3, 26.0.0, 26.0.1, 26.0.2, 26.0.3, 27.0.0, 27.0.1, 27.0.3, 28.0.0, 28.0.0, 28.0.2, 28.0.3
    System Images: android-16 | ARM EABI v7a, android-16 | MIPS, android-16 | Intel x86 Atom, android-16 | Google APIs Intel x86 Atom, android-19 | Google APIs Intel x86 Atom, android-24 | Google Play Intel x86 Atom, android-26 | Google APIs Intel x86 Atom, android-26 | Google APIs Intel x86 Atom_64, android-26 | Google Play Intel x86 Atom, android-27 | Google Play Intel x86 Atom, android-28 | Google APIs Intel x86 Atom, android-P | Google APIs Intel x86 Atom, android-P | Google Play Intel x86 Atom
IDEs:
  Android Studio: 3.2 AI-181.5540.7.32.5056338
  Xcode: 10.1/10B61 - /usr/bin/xcodebuild
npmPackages:
  react: 16.6.0-alpha.8af6728 => 16.6.0-alpha.8af6728 
  react-native: 0.57.4 => 0.57.4 
npmGlobalPackages:
  babel-preset-react-native: 4.0.0
  react-native-cli: 2.0.1
  react-native-create-library: 3.1.2
  react-native-git-upgrade: 0.2.7

Description

I’m not able to create a release apk with the PNG image in Android. But can able to create a release apk when there is no PNG image in it. Here is the error I’m getting while generating the release build

[drawable-mdpi-v4/assets_mario] /Users/jeffreyrajan/Tutorials/RN/errorCheck/android/app/src/main/res/drawable-mdpi/assets_mario.png	[drawable-mdpi-v4/assets_mario] /Users/jeffreyrajan/Tutorials/RN/errorCheck/android/app/build/generated/res/react/release/drawable-mdpi-v4/assets_mario.png: Error: Duplicate resources
:app:mergeReleaseResources FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:mergeReleaseResources'.
> [drawable-mdpi-v4/assets_mario] /Users/jeffreyrajan/Tutorials/RN/errorCheck/android/app/src/main/res/drawable-mdpi/assets_mario.png	[drawable-mdpi-v4/assets_mario] /Users/jeffreyrajan/Tutorials/RN/errorCheck/android/app/build/generated/res/react/release/drawable-mdpi-v4/assets_mario.png: Error: Duplicate resources

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Reproducible Demo

  1. Create a app — react-native init demo
  2. Create a assets folder in the project root folder.
  3. Add a PNG image inside the assets folder.
  4. Now implement a image component with the above PNG image.
  5. Now bundle it using the cmd
    react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/
  6. Then generate release apk using Generate Signed APK

Hi Guys, In this article, we are learning about Duplicate resources React Native Android error. generally, we face this error while creating a signed apk or production build. To create React Native Android build we need to create index.android.bundle inside the asset folder. to create this bundle check this post. after creating this bundle you will be able to reproduce this error in Android studio. so basically bundle creation process creates duplicates of drawable files in the project. to solve this error we have to delete duplicate resources files then we have to add some code in node modules react-native Gradle file then create build again and the error will be fixed, so let’s solved it step by step.

You will see the following error in android studio.Duplicate resources React Native Android

So, do not panic after facing this error. try the following solution and you can able to fix this error

1. Try cleaning the Android project.

In the terminal project root folder, go to the android folder using cd android. Using the following comment to clean the android project.

./gradlew clean

2. Try deleting the drawable folder

After creating the bundle delete the drawable folder from Android Studio. You could find this in the path android/app/src/main/res/drawable

3. Add the following code in react.gradle

Add the following code below doFirst in path node_modules/react-native/react.gradle. save this file and we have to create build again. check this post for the command to create a build. also, you can now delete duplicate resources from the drawable folder then clean and build the project.

doLast {
    def moveFunc = { resSuffix ->
        File originalDir = file("${resourcesDir}/drawable-${resSuffix}");
        if (originalDir.exists()) {
            File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}");
            ant.move(file: originalDir, tofile: destDir);
        }
    }
    moveFunc.curry("ldpi").call()
    moveFunc.curry("mdpi").call()
    moveFunc.curry("hdpi").call()
    moveFunc.curry("xhdpi").call()
    moveFunc.curry("xxhdpi").call()
    moveFunc.curry("xxxhdpi").call()
}

I was getting the same duplicate resources React Native Android error while creating the signed APK and I solved this error using the same solution. try this solution and let me know if any other issues. and make sure you need to refresh the project & run the project again to reflect these changes.

Thank you.

During Android development we often have to manage many different resources. At compilation time these resources are all gathered up and merged together into a single package.

As per the ‘The build process’ in the Configure your build documentation

  1. The compilers convert your source code into DEX (Dalvik Executable) files, which include the bytecode that runs on Android devices, and everything else into compiled resources.
  1. The APK Packager combines the DEX files and compiled resources into a single APK. …

But what happens if there is a resource naming collision? Turns out that “it depends”, especially when libraries are involved. In this article we’ll explore some different resource collision cases and look at what it means to have good resource naming hygiene.

In the App Module

In the simplest case we have a collision between two resources with the same name and type in the same file, like in the following example:

<!--strings.xml-->
<resources>
    <string name="hello_world">Hello World!</string>
    <string name="hello_world">Hello World!</string>
</resources>

Attempting to compile this results in a very self explanatory error message:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:mergeDebugResources'.
> /.../strings.xml: Error: Found item String/hello_world more than one time

Similarly if we were to define these resources over multiple files:

<!--strings.xml-->
<resources>
    <string name="hello_world">Hello World!</string>
</resources>

<!--other_strings.xml-->
<resources>
    <string name="hello_world">Hello World!</string>
</resources>

We get a similar compilation error, however this time listing both files involved in the conflict:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:mergeDebugResources'.
> [string/hello_world] /.../other_strings.xml
  [string/hello_world] /.../strings.xml: Error: Duplicate resources

The way resources work in Android starts to become apparent. In our app module we need to be able to resolve a unique resource for the combination of type, name and device configuration. That is, there needs to be only one resolvable value for string/hello_world when referenced from the app module. We (the developer) are expected to resolve this conflict by either removing the resource (if it is a duplicate), renaming one of the instances or by moving one instance to a resource file with an appropriate qualifier. More information on resources and qualifiers can be found in the App resources overview documentation.

Library and App Module

The next case we’ll investigate is when we have a resource defined in a library module and the duplicate defined in our app module:

<!--app/../strings.xml-->
<resources>
    <string name="hello">Hello from the App!</string>
</resources>

<!--library/../strings.xml-->
<resources>
    <string name="hello">Hello from the Library!</string>
</resources>

Attempting to compile this… succeeds! From our previous discoveries we can now infer that Android must have a rule for resolving a single value for string/hello when encountering this scenario.

As per the Create an Android library documentation

The build tools merge resources from a library module with those of a dependent app module. If a given resource ID is defined in both modules, the resource from the app is used.

However what implications does this have when building a modularised application? Say we define the following view in our library:

<!--library/../text_view.xml-->
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    xmlns:android="http://schemas.android.com/apk/res/android" />

Looking at the preview for this view shows us:

Hello from the Library!

And now when we decide to include the text view layout in a layout inside the app module:

<!--app/../activity_main.xml-->
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    tools:context=".MainActivity"
    >

    <include layout="@layout/text_view" />

</LinearLayout>

When looking at the preview / the running application we can see that the text displays as:

Hello from the App!

Not only does accessing string/hello from a layout in the app module resolve to “Hello from the App!” but the app module’s version is also used for layouts included from libraries! For this reason we need to be wary of overriding resources defined in libraries when we don’t mean to.

Two Libraries

In the final case we’ll look at what happens when conflicting resources are defined in two libraries. Following on from our previous example, if we have a setup like:

<!--library1/../strings.xml-->
<resources>
    <string name="hello">Hello from Library 1!</string>
</resources>

<!--library2/../strings.xml-->
<resources>
    <string name="hello">Hello from Library 2!</string>
</resources>

<!--app/../activity_main.xml-->
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello" />

What will be rendered for the value string/hello? Turns out it depends on the ordering of dependencies in our app’s build.gradle.

Again from the Create an Android library documentation

If conflicts occur between multiple AAR libraries, then the resource from the library listed first in the dependencies list (toward the top of the dependencies block) is used.

This means for the configuration:

dependencies {
    implementation project(":library1")
    implementation project(":library2")
    ...
}

The value of string/hello will be Hello from Library 1!. Subsequently if the two implementation lines are reordered such that implementation project(":library2") comes before implementation project(":library1") then the value will be Hello from Library 2!. This is quite a subtle effect and it’s pretty easy to see how it could result in unintended behaviour for our application.

Custom Attributes

So far all of our examples have been making use of string resources, however an interesting resource type to take particular notice of is custom attributes.

Consider the following definition:

<!--app/../attrs.xml-->
<resources>
    <declare-styleable name="CustomStyleable">
        <attr name="freeText" format="string"/>
    </declare-styleable>

    <declare-styleable name="CustomStyleable2">
        <attr name="freeText" format="string"/>
    </declare-styleable>
</resources>

One may think that the following would compile without issue, however when defined in the app module we get the following compilation error:

Execution failed for task ':app:mergeDebugResources'.
> /.../attrs.xml: Error: Found item Attr/freeText more than one time

And if each custom attribute is defined across two libraries like so:

<!--library1/../attrs.xml-->
<resources>
    <declare-styleable name="CustomStyleable">
        <attr name="freeText" format="string"/>
    </declare-styleable>
</resources>

<!--library2/../attrs.xml-->
<resources>
    <declare-styleable name="CustomStyleable2">
        <attr name="freeText" format="string"/>
    </declare-styleable>
</resources>

It… compiles. However if we change library2’s definition to be a different format (e.g. <attr name="freeText" format="boolean"/>) we get the much more obtuse compilation error:

* What went wrong:
Execution failed for task ':app:mergeDebugResources'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
   > Android resource compilation failed
     /.../library2/build/intermediates/packaged_res/debug/values/values.xml:4:5-6:25: AAPT: error: duplicate value for resource 'attr/freeText' with config ''.
     /.../library2/build/intermediates/packaged_res/debug/values/values.xml:4:5-6:25: AAPT: error: resource previously defined here.
     /.../app/build/intermediates/incremental/mergeDebugResources/merged.dir/values/values.xml: AAPT: error: file failed to compile.

One important part of the message to look into is: mergeDebugResources/merged.dir/values/values.xml: AAPT: error: file failed to compile.

What’s going on here? The compilation of values.xml actually refers to the generation of the R class for the app module. During this compilation AAPT is trying to generate a single value for each of the properties for our R class. For each custom attribute inside a styleable there are actually two R class values which are generated. The first is the styleable name spaced value (under R.styleable), the second is the global value (under R.attr). For our particular case we are getting a collision on the global value, and due to the naming collision there are only three values to resolve as detailed below:

  • R.styleable.CustomStyleable_freeText which is the value from library1 resolves to the attribute freeText with a format of string
  • R.styleable.CustomStyleable2_freeText which is the value from library2 resolved to the attribute freeText with a format of boolean
  • R.attr.freeText this value cannot be resolved as we have included values from both library1 and library2 and their format’s differ, this causes a collision.

In the first case where the format was the same across libraries R.attr.freeText was resolved to a single definition for the app module.

It’s worth noting at this time that each module has its own R class generated. We can’t always expect the value to remain consistent across our modules. Again from the Create an Android library documentation

When you build the dependent app modules, library modules are compiled into an AAR file then added to the app module. Therefore, each library has its own R class, named according to the library’s package name. The R class generated from main module and the library module is created in all the packages that are needed including the main module’s package and the libraries’ packages.

Conclusion

So what do we take away from all of this? That resource compilation is complex and nuanced? Well actually, yes. However there are things that we can do as a developer to make what is going on obvious to ourselves and our team, namely resource prefixing. From our favourite Create an Android library documentation there is this hidden gem:

To avoid resource conflicts for common resource IDs, consider using a prefix or other consistent naming scheme that is unique to the module (or is unique across all project modules).

Taking on this advice, it would be a good idea to establish a pattern in our projects and teams where we prefix all resources in modules with the module name e.g. library_help_text. This has two side effects:

  1. It decreases the chance of collision considerably.
  2. It makes overrides explicit.
    E.g. creating library_help_text in the app module is now clearly overriding something in the library module. Sometimes we do want to perform these overrides and using prefixes helps to make it clear what is occurring during the build process.

At a minimum all public resources should be prefixed, especially when distributing our library as a vendor or as an open source project. From experience not all of the resources in Google’s own library’s are prefixed appropriately. This can have the unfortunate side effect of the inclusion of our library causing an app compilation to fail due to a naming collision. Not a great look!

For instance we can see the material design library prefixes their color resources consistently with mtrl. However the attribute resources nested under a styleable are not prefixed with material. As we have seen, this has the potential to conflict when generating the R class for a module which includes both the material library and a library containing an attribute of the same name but different format.

Acknowledgements

The creation of this blog post was assisted by the following content:

  • Android Resources collision without warning!
  • Why Android cannot deal with Resources name conflict between Project and Library?

Понравилась статья? Поделить с друзьями:
  • Error duet display splashtop fresco logic etc driver detected incompatible display hook driver
  • Error due to multiple causes
  • Error due to incompatibility with several python libraries что это
  • Error due to incompatibility with several python libraries destination folder
  • Error ds createsoundbuffer