0:00
This audio is presented by Hacker Nune, where anyone can learn anything about any technology.
0:05
How InDrive detects silent Android resource overrides before merge? By InDrive,
0:10
tech, silent resource overriding is one of those Android problems that looks
0:14
menoruntil it affects something important. Most Android developers have encountered situations where
0:20
a resource file in the app unexpectedly overrides an existing system or library resource.
0:26
The Android build system merges everything successfully, the build stays green, and there
0:30
is no warning. At first glance, this may look like a harmless technical detail.
0:36
In practice, it can quietly change app behavior in ways that are difficult to notice during code
0:40
review. At InDrive, we wanted a practical way to make these conflicts visible earlier,
0:45
without adding unnecessary complexity to daily development. So instead of trying to redesign
0:51
the whole resource strategy, we added a lightweight C guardrail that warns engineers about
0:55
potentially dangerous duplicates right in pull requests. The problem with silent resource overriding,
1:01
as the official Android documentation explains, greater than avoid resource merge conflicts.
1:07
Greater than the build tools merge resources from a library module with those of a greater than
1:12
dependent app module. If a given resource name is defined in both modules, the greater than
1:17
resource from the app is used. If conflicts occur between multiple R greater than libraries,
1:23
then the resource from the library listed first in the dependencies greater than list,
1:27
closest to the top of the dependencies block is used. To avoid resource greater than conflicts,
1:33
consider using a prefix or other consistent naming scheme that is greater than unique to the module,
1:38
or as unique across all project modules. That behavior is well documented, but it is still
1:44
easy to underestimate the risk. If a conflict affects a minor UI detail or a low priority message,
1:50
the impact may be negligible. But if it touches something more sensitive,
1:54
authentication, authorization, navigation, or another critical flow, the consequences can be
2:00
much more serious. The most dangerous part is that the override happens silently. Nothing fails,
2:06
nothing alerts you. The issue may remain unnoticed until much later. Why the obvious solution is not
2:11
always the best one. A common recommendation is to introduce consistent prefixes for resources
2:17
and enforce them with Lint rules. That is a valid approach, and in many projects it works well.
2:23
But real-world development is usually messier than ideal guidelines suggest. Sometimes resource
2:28
overriding is intentional. Sometimes strict prefixing ADDS friction for developers. And sometimes the
2:34
bigger issue is not the existence of overrides, but the lack of visibility around them. At InDrive,
2:40
we wanted a solution that would not slow engineers down or force a new naming discipline across
2:45
every case. We wanted a simple warning mechanism. If a newly added resource duplicates an existing one,
2:51
the author should see it immediately and decide whether it is intentional. A simple idea,
2:57
detect duplicates in pull requests. The logic is straightforward. When a pull request adds new
3:02
Android resource files, compare them with resources that already exist in the project.
3:07
If duplicates are found, show a warning to the developer. This does not attempt to fix
3:13
Android resource merging globally. It simply makes hidden conflicts visible early enough to be
3:18
reviewed consciously. First implementation. Bash Plus git checkout. Our first version was based
3:24
on history. The workflow checked out the repository, detected newly added resource files,
3:30
filtered out standard XML files such as AND, and then compared those files with the existing
3:35
project tree. This version worked, but it came with an obvious drawback. It was too heavy
3:40
fourth amount of useful work it actually did. To compare new files against the existing tree,
3:45
we had to fetch history and perform a checkout. In our project, the full workflow took about three
3:51
minutes, while the actual duplicate detection logic needed only a few seconds. That made the
3:56
next step clear. Faster version. GitHub API Plus. To improve both speed and readability,
4:02
we removed the checkout step and moved the same logic to the GitHub API through.
4:07
Instead of cloning repository history locally, we listed files changed in the pull request.
4:13
Filtered added files under, excluded standard resource file names,
4:18
requested the base branch tree through the GitHub API, searched for matching resource pads there.
4:23
This kept the approach simple, but made it much more practical to run and see.
4:28
In our case, the average execution time dropped from roughly three minutes T.O. about eight seconds.
4:34
That change alone made the workflow much easier to justify in a real engineering pipeline.
4:39
What this solution improves, this approach gave us several immediate benefits. First,
4:44
it made silent conflicts visible during review. Instead of discovering issues later through manual
4:50
testing or unexpected behavior, engineers now get a signal at the pull request stage.
4:55
Second, it reduced friction. We did not need to introduce a strict naming migration or force
5:00
prefixes into cases where overriding was intentional. Third, it stayed lightweight.
5:05
For in drive, that mattered a lot. A guardrail IS useful only if it protects quality without
5:10
making the development workflow noticeably slower or more complicated. Limitations and trade-offs,
5:16
this solution is intentionally pragmatic, not universal. It checks duplicate resource files inside
5:22
project modules already present in the repository. That is enough to catch a meaningful class of
5:27
mistakes early, but it does not cover every possible merge scenario. Its main limitations are
5:33
straightforward. It does not inspect resources coming from external libraries or AAR, JAR
5:38
dependencies. It depends on the GitHub API tree response, which may be truncated in very large
5:44
repositories. It does not validate the assets folder. It warns about duplicates, but does not decide
5:51
whether a given override is correct or incorrect. A deeper Gradle or AAPT level integration could
5:57
potentially catch more cases. But it would also make the solution more complex, slower, and harder
6:02
to maintain. For us, that trade-off was not worth it. Why this was enough? We did not need a
6:08
perfect detector for every Android resource conflict across the whole dependency graph.
6:13
We needed a fast, understandable, low friction safety net that could catch the most
6:17
relevant risks before merge. This workflow does exactly that. It improves visibility.
6:23
It keeps C efficient, and it gives developers a chance at o confirm whether a duplicate resource
6:28
is intentional or accidental. Sometimes the best engineering solution is not the most comprehensive one.
6:34
It is the one that fits the team's workflow, solves the most painful part of the problem,
6:39
and remains cheap enough to use every day. At InDrive, this small GitHub workflow turned out to be a
6:45
practical way to reduce the risk of unintentional Android resource overriding, without turning a
6:50
solve-able problem into a heavyweight process. Reference, Android documentation on resource merge
6:56
conflicts, HTTPS colon slash slash developer, Android, COM, Studio, Projects, Android Library,
7:04
thank you for listening to this Hackernoun story, read by artificial intelligence.
7:09
Visit Hackernoun.com to read, write, learn, and publish.