Skip to content

refactor: modernize --res-resolve-mode and dummies#4044

Merged
iBotPeaches merged 1 commit into
mainfrom
rrm-update
Dec 14, 2025
Merged

refactor: modernize --res-resolve-mode and dummies#4044
iBotPeaches merged 1 commit into
mainfrom
rrm-update

Conversation

@IgorEisberg
Copy link
Copy Markdown
Collaborator

  • Since --res-resolve-mode has a new name in 3.x we can afford to update the modes to better describe their meaning.
  • default: Adds dummy entries only for resources that cannot be resolved.
    (this is done after ARSC parsing, during resolution and res file decoding stages)
  • greedy: Adds dummy entries for all missing resources in the resource table.
    (this is done during ARSC parsing, at the end of each package)
  • lazy: Ignores resources that are missing or cannot be resolved.

(Docs will be updated after merge.)

  • APKTOOL_MISSING_ is now also APKTOOL_DUMMY_ (they are the same thing, just were added at different stages).

  • Improve dummy serialization based on each item/bag type's default value.

Case study:

<resources>
    <anim name="DUMMY" />
    <animator name="DUMMY" />
    <array name="DUMMY" />
    <attr name="DUMMY" />
    <bool name="DUMMY" />
    <color name="DUMMY" />
    <dimen name="DUMMY" />
    <drawable name="DUMMY" />
    <font name="DUMMY" />
    <fraction name="DUMMY" />
    <id name="DUMMY" />
    <integer name="DUMMY" />
    <interpolator name="DUMMY" />
    <layout name="DUMMY" />
    <menu name="DUMMY" />
    <mipmap name="DUMMY" />
    <plurals name="DUMMY" />
    <raw name="DUMMY" />
    <string name="DUMMY" />
    <style name="DUMMY" />
    <transition name="DUMMY" />
    <xml name="DUMMY" />
</resources>

aapt2 dump resources:

type anim id=01 entryCount=1
  resource 0x7f010000 anim/DUMMY
    () @null
type animator id=02 entryCount=1
  resource 0x7f020000 animator/DUMMY
    () @null
type array id=03 entryCount=1
  resource 0x7f030000 array/DUMMY
    () (array) size=0
      []
type attr id=04 entryCount=1
  resource 0x7f040000 attr/DUMMY
    () (attr) type=any
type bool id=05 entryCount=1
  resource 0x7f050000 bool/DUMMY
    () @null
type color id=06 entryCount=1
  resource 0x7f060000 color/DUMMY
    () @null
type dimen id=07 entryCount=1
  resource 0x7f070000 dimen/DUMMY
    () @null
type drawable id=08 entryCount=1
  resource 0x7f080000 drawable/DUMMY
    () @null
type font id=09 entryCount=1
  resource 0x7f090000 font/DUMMY
    () @null
type fraction id=0a entryCount=1
  resource 0x7f0a0000 fraction/DUMMY
    () @null
type id id=0b entryCount=1
  resource 0x7f0b0000 id/DUMMY
    () (id)
type integer id=0c entryCount=1
  resource 0x7f0c0000 integer/DUMMY
    () @null
type interpolator id=0d entryCount=1
  resource 0x7f0d0000 interpolator/DUMMY
    () @null
type layout id=0e entryCount=1
  resource 0x7f0e0000 layout/DUMMY
    () @null
type menu id=0f entryCount=1
  resource 0x7f0f0000 menu/DUMMY
    () @null
type mipmap id=10 entryCount=1
  resource 0x7f100000 mipmap/DUMMY
    () @null
type plurals id=11 entryCount=1
  resource 0x7f110000 plurals/DUMMY
    () (plurals) size=0
type raw id=12 entryCount=1
  resource 0x7f120000 raw/DUMMY
    () @null
type string id=13 entryCount=1
  resource 0x7f130000 string/DUMMY
    () ""
type style id=14 entryCount=1
  resource 0x7f140000 style/DUMMY
    () (style) size=0
type transition id=15 entryCount=1
  resource 0x7f150000 transition/DUMMY
    () @null
type xml id=16 entryCount=1
  resource 0x7f160000 xml/DUMMY
    () @null

We learn that:

  • default value for bag types (array, attr, plurals, style) is an empty bag of the given type.
  • default value for id type is a special placeholder (we already handled that).
  • default value for string type is the empty string ("").
  • default value for the rest of the item types is @null.

Use that to serialize them accordingly and add dummies with the appropriate default value.
The result is avoiding unnecessary <item> tags and unnecessary @nulls where empty tags mean the same.
Much cleaner output, <item> tags are used only when it's unavoidable.

Also added a few test cases for this.

* Since --res-resolve-mode has a new name in 3.x we can afford to update the modes to better describe their meaning.

- default: Adds dummy entries only for resources that cannot be resolved.
  (this is done after ARSC parsing, during resolution and res file decoding stages)
- greedy: Adds dummy entries for all missing resources in the resource table.
  (this is done during ARSC parsing, at the end of each package)
- lazy: Ignores resources that are missing or cannot be resolved.

(Docs will be updated after merge.)

* APKTOOL_MISSING_ is now also APKTOOL_DUMMY_ (they are the same thing, just were added at different stages).

* Improve dummy serialization based on each item/bag type's default value.

Case study:

<resources>
    <anim name="DUMMY" />
    <animator name="DUMMY" />
    <array name="DUMMY" />
    <attr name="DUMMY" />
    <bool name="DUMMY" />
    <color name="DUMMY" />
    <dimen name="DUMMY" />
    <drawable name="DUMMY" />
    <font name="DUMMY" />
    <fraction name="DUMMY" />
    <id name="DUMMY" />
    <integer name="DUMMY" />
    <interpolator name="DUMMY" />
    <layout name="DUMMY" />
    <menu name="DUMMY" />
    <mipmap name="DUMMY" />
    <plurals name="DUMMY" />
    <raw name="DUMMY" />
    <string name="DUMMY" />
    <style name="DUMMY" />
    <transition name="DUMMY" />
    <xml name="DUMMY" />
</resources>

aapt2 dump resources:

type anim id=01 entryCount=1
  resource 0x7f010000 anim/DUMMY
    () @null
type animator id=02 entryCount=1
  resource 0x7f020000 animator/DUMMY
    () @null
type array id=03 entryCount=1
  resource 0x7f030000 array/DUMMY
    () (array) size=0
      []
type attr id=04 entryCount=1
  resource 0x7f040000 attr/DUMMY
    () (attr) type=any
type bool id=05 entryCount=1
  resource 0x7f050000 bool/DUMMY
    () @null
type color id=06 entryCount=1
  resource 0x7f060000 color/DUMMY
    () @null
type dimen id=07 entryCount=1
  resource 0x7f070000 dimen/DUMMY
    () @null
type drawable id=08 entryCount=1
  resource 0x7f080000 drawable/DUMMY
    () @null
type font id=09 entryCount=1
  resource 0x7f090000 font/DUMMY
    () @null
type fraction id=0a entryCount=1
  resource 0x7f0a0000 fraction/DUMMY
    () @null
type id id=0b entryCount=1
  resource 0x7f0b0000 id/DUMMY
    () (id)
type integer id=0c entryCount=1
  resource 0x7f0c0000 integer/DUMMY
    () @null
type interpolator id=0d entryCount=1
  resource 0x7f0d0000 interpolator/DUMMY
    () @null
type layout id=0e entryCount=1
  resource 0x7f0e0000 layout/DUMMY
    () @null
type menu id=0f entryCount=1
  resource 0x7f0f0000 menu/DUMMY
    () @null
type mipmap id=10 entryCount=1
  resource 0x7f100000 mipmap/DUMMY
    () @null
type plurals id=11 entryCount=1
  resource 0x7f110000 plurals/DUMMY
    () (plurals) size=0
type raw id=12 entryCount=1
  resource 0x7f120000 raw/DUMMY
    () @null
type string id=13 entryCount=1
  resource 0x7f130000 string/DUMMY
    () ""
type style id=14 entryCount=1
  resource 0x7f140000 style/DUMMY
    () (style) size=0
type transition id=15 entryCount=1
  resource 0x7f150000 transition/DUMMY
    () @null
type xml id=16 entryCount=1
  resource 0x7f160000 xml/DUMMY
    () @null

We learn that:
- default value for bag types (array, attr, plurals, style) is an empty bag of the given type.
- default value for id type is a special placeholder (we already handled that).
- default value for string type is the empty string ("").
- default value for the rest of the item types is @null.

Use that to serialize them accordingly and add dummies with the appropriate default value.
The result is avoiding unnecessary <item> tags and unnecessary @null's where empty tags mean the same.
Much cleaner output, <item> tags are used only when it's unavoidable.

Also added a few test cases for this.
@iBotPeaches iBotPeaches added this to the 3.0.0 milestone Dec 14, 2025
@iBotPeaches iBotPeaches merged commit 87eb072 into main Dec 14, 2025
18 checks passed
@iBotPeaches iBotPeaches deleted the rrm-update branch December 14, 2025 11:55
iBotPeaches added a commit to iBotPeaches/apktool.org that referenced this pull request Dec 14, 2025
@SuggonM
Copy link
Copy Markdown

SuggonM commented Mar 30, 2026

  • Since --res-resolve-mode has a new name in 3.x we can afford to update the modes to better describe their meaning.

    • default: Adds dummy entries only for resources that cannot be resolved.
      (this is done after ARSC parsing, during resolution and res file decoding stages)

    • greedy: Adds dummy entries for all missing resources in the resource table.
      (this is done during ARSC parsing, at the end of each package)

    • lazy: Ignores resources that are missing or cannot be resolved.

@IgorEisberg Hi. Looking at the changes, I can see that the equivalent resource resolving modes are now: (correct me if it's wrong)

  • remove | delete -> default
  • dummy | dummies -> lazy
  • keep | preserve -> greedy

Could you clarify if these differ from the past behavior in any way? I also found from searches that the documentation is still using the old option name (-resm) and values. Is it possible to get it updated?

https://apktool.org/wiki/in-depth/resource-modes/#modes

@IgorEisberg
Copy link
Copy Markdown
Collaborator Author

You can refer to usage here: https://apktool.org/docs/cli-parameters#decoding-options
Yes, the behavior is different. default prioritizes maximum rebuildability with minimum dummy resources, lazy doesn't produce dummy resources at all, while greedy produces all possible dummy resources early (before resolution) which produces bloat and affects entry names. Both lazy and greedy are useless for normal usage.

@SuggonM
Copy link
Copy Markdown

SuggonM commented Mar 31, 2026

@IgorEisberg Thanks, that helps clarify behavior. I’m still a bit unsure about how the old modes map to the new ones though.

If a project was previously using -resm dummy, would omitting the flag (i.e. --res-resolve-mode default) be the closest equivalent now?

This is especially confusing because when reading the documentation you linked, default sounds closer to dummy, whereas looking at the changelog it seems to claim that the default mode was effectively changed from REMOVE to KEEP. https://github.com/iBotPeaches/apktool.org/blob/7b0dc0ba4e946af9d6f7bb960c66027ca1e9349c/docs/unreleased.mdx#L22

Edit: Since it's already been mentioned that the other two modes aren't very useful, I'll simply go with default instead of complicating it further. Thanks again for the guidance!

@IgorEisberg
Copy link
Copy Markdown
Collaborator Author

default is closest to keep, lazy to remove, greedy to dummy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants