23

How do I make the resources (string, dimen, color, etc.) in my Android library module private?

I've tried both documented ways of doing this and neither work...

  1. Following the official Android doc of creating a res/values/public.xml does not work; all of the resources remain public in the app that uses this library.
  2. Following Chris Banes's instruction (and reiterated in this StackOverflow answer) of creating a res-public/values/public.xml folder does not work either; all of the resources are made private, but those listed in the public.xml file are not made public as they should be.

Does anyone have the definitive instructions for making library resources private? Are there any open-source libraries out there that have properly made their resources private?

I'm using...

  • Android Studio v2.2.3
  • buildToolsVersion "24.0.2"
  • com.android.tools.build:gradle:2.2.3
2
  • 3
    appcompat-v7 uses this. If you look in the AAR, you will see public.txt, which is generated based on this information, and it uses res-public. Ditto the design support library and its material-android successor. Commented Jan 25, 2017 at 23:40
  • Thanks, @CommonsWare. Those links helped me get to the root of my problem... I had the incorrect path when referencing my res and res-public folders in my build.gradle sourceSets. Commented Jan 26, 2017 at 2:15

2 Answers 2

14

Your resources are assumed to be public in any module (library, etc) unless you start, explicitly, declaring any resource in the module to be public. At that point you basically opt-in to every resource (within the module) being private except what you mark as public. This preserves backward compatibility and let's you incrementally tighten down access in large projects with many modules.

To make all resources private simply add <public /> to any of your existing resource files.

The above answer talks about adding a specific resource directory just to manage the public/private modifiers. While that works, I might suggest you manage the visibility and declaration in the main resource files next to where they are declared. Here's a sample strings.xml resource file I used with a brand new library module. The public/private prefix in the string names is for illustrative purposes only.

res/values/strings.xml

<resources> <string name="app_name">My Library2</string> <public type="string" name="public_string_in_lib2" /> <string name="public_string_in_lib2">public string in lib2</string> <string name="private_string_in_lib2">private string in lib2</string> </resources> 

Fundamentally, these qualifications are being used to create a public.txt file that is embedded in the AAR that will be depended upon by another module. Various pieces of tooling like Android Studio will use this information to flag/warn, but technically, a consumer of the library isn't prevented from using the resource unless their tooling is being really strict.

Sign up to request clarification or add additional context in comments.

Comments

4

Option #2 actually works. I had not properly defined my sourceSets in my build.gradle...

sourceSets { main.res.srcDirs = [ 'src/main/res', 'src/main/res-public' ] } 

5 Comments

Could you, please, share the solution? It doesn't work for me :(
@Gus The above solution didn't work for me. Still, I am able to access the private resources in the Main app module
@AKASHWANGALWAR check out this android doc, developer.android.com/studio/projects/…
How you manage to get it worked? Its not working for me (Gradle plugin: 3.3.1)
Resource privatisation means, you won't see them in lint or suggestions. But if you know you can access them. My question is how to have 2 sets of folder for resources in two different place? I am getting error res/values already exist, please try different qualifier

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.