Time for my ever so-often update for the crowd here. This morning I
merged a feature that fixed a Windows issue with commands becoming too long. This happens with applications built by Unity (and others), as assets are frequently stored or compressed which Apktool needs to know about. Apktool then passes a command to aapt which is sometimes upwards of 3,000 characters in length. Windows is the only operating system that has a problem about this. I did a solid amount of research (
#1 /
#2 /
#3) in hopes to "stage" the steps that aapt does. This would allow Windows to work around the small limitation it has when it comes to commands.
I ended up building my own "apk" builder, which was nothing more than a glorified .zip creator. It took compression type into account when adding files into the application. The problem is that you can't modify the compression type of a file in a zip easily using only aapt. The options are basically, remove that file and then re-add it with the compression type you prefer. So if I accidentally built the application with a compressed "
ic_sysbar_back_carmode.webp" file, then I needed to remove that file before I attempted adding it again in the STORED format. This took some engineering, hence why the pull request ended up changing a good deal of code. I basically don't add files to the application that I intend to add manually without compression. It finally worked and I was excited, it passed all testing and was merged.
Unfortunately, success was short-lived. As a side affect of now storing the entire directory path of the file, we included the directory the asset in question was from. In the example above this was "
SystemUI/res/drawable-ldrtl-xxhdpi-v4/ic_sysbar_back_carmode.webp".
Apktool works by decoding the
resources.arsc which leads to decoding each configuration in the application and finding resources in that configuration. We can see that the configuration above is "
ldrtl-xxhdpi-v4", but aapt and by extension Apktool don't see the "
v4" portion.
➜ Bug1761 aapt d configurations SystemUI.apk | grep 'ldrtl-xxxhdpi'
ldrtl-xxxhdpi
This is because "
v4" is an implicit sdk version added by the aapt binary. No one building this example application added that qualifier, it was automatic. Here comes the problem. The 56 byte header for that qualifier does not list anything about an SDK version. It only tells me "
ldtrl" and "
xxhdpi", if the qualifiers used were from API21 like "
notround", then its obvious to know a SDK level should be added. This qualifier was added by aapt/aapt2 because it scanned a massive
hardcoded list of attributes in order to determine what qualifier that resource should be under. It actually does this crazy thing and "strip" resources to versioned qualifiers on its own. The long story is Apktool does not read the file (AXML) to determine the attributes used, so it cannot determine this. It might be able too in the future, but Java is not blazing speed low level C++. It would have to use like an XML reader (PullParser) to read each attribute. It therefore, currently, drops those version qualifiers unless they were explicitly provided. This means an uncompressed asset is recorded in file-system, but then the qualifier processed file-path is different (missing the implicit version qualifier).
This means my patch broke lots of applications (None of which that were in testing). This caused errors like
java.io.FileNotFoundException: SystemUI/res/drawable-ldrtl-xxhdpi-v4/ic_sysbar_back_carmode.webp (No such file or directory)
So I had to
revert the fix. This means Windows support for large application is still broken. It means that version v2.3.2 will have a release this weekend, but not with all the intended features I hoped. I apologize and we will fix these in time.