Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

StreamingAssets files are compressed in APK when "Build App Bundle (Google Play)" option is used

Discussion in 'Android' started by Unity_User_2, Sep 5, 2019.

  1. Unity_User_2

    Unity_User_2

    Joined:
    Aug 23, 2017
    Posts:
    2
    1. What happened

    We uploaded Android App Bundle (aab) to Google Play which was build with "Build App Bundle (Google Play)" option enabled in Unity (2019.2).
    Then we noticed the problem that some StreamingAssets files are not loaded during runtime. Our app loads these files directly as byte sequence assuming that they are stored uncompressed inside APK.
    So we get APK sample based on the uploaded aab and found out that these files are stored compressed (using HEX-editor on APK).
    We checked all SteamingAssets files in our app and concluded that this issue takes place only for files that have uppercase letters in their path (relative to StreamingAssets).

    Same behaviour in 2019.2.1, 2019.2.2.

    2. How we can reproduce it using the example you attached

    Sample project is just a new project created in Unity 2019.2 with ILL2CPP and ARM64 enabled for Android. Also there are some test files in StreamingAssets folder.
    2.1. Build Android App Bundle file (aab) from Unity 2019.2.
    2.2. Get APK from this aab using bundletool.
    2.3. Use HEX-editor on APK to check which files from StreamingAssets are stored uncompressed.
    StreamingAssets files in this project are:
    StreamingAssets/file1.txt
    StreamingAssets/File2.txt
    StreamingAssets/folder1/file3.txt
    StreamingAssets/folder1/File4.txt
    StreamingAssets/Folder2/file5.txt
    So only file1 and file3 are stored uncompressed. Their paths do not contain uppercase letters (relative to StreamingAssets).
    2.4. Export Android Studio project with "Build App Bundle (Google Play)" enabled
    2.5. Check build.gradle. noCompress section has all StreamingAssets files in lowercase:
    aaptOptions {
    noCompress = ['.unity3d', '.ress', '.resource', '.obb', 'file2.txt', 'file1.txt', 'folder2/file5.txt', 'folder1/file4.txt', 'folder1/file3.txt']
    ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~"
    }
     

    Attached Files:

  2. ShadowAngel

    ShadowAngel

    Joined:
    Aug 7, 2012
    Posts:
    5
    Got similar problem with aab. I can read anything that in StreamingAssets folder root. But anything that is in sub folders unity can't access. Instead i get DirectoryNotFoundException. If i use apk, everything works fine.
     
  3. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    2,528
    There are known problems with app bundle tools with regard to compression. This is not Unity bug, but rather Google tools bug, so you have to work that around until tools are fixed and updated.
    As you've found, uppercase letters cause problems. IIRC the behavior is different depending on which OS you build on. When using a mix of all lowercase and uppercase/mixed case file names, you get some of those files compressed, but not the same one depending on whether you are on Windows or not (could be case-insensitive vs. case-sensitive file system, we haven't digged that deep).
    A workaround is to use all lowercase file names.
     
    hayone1 and Egil-Sandfeld like this.
  4. nik_d

    nik_d

    Joined:
    Apr 27, 2018
    Posts:
    60
    Other workaround is just to fix build.gradle file generated by
    UnityEngine.BuildPipeline.BuildPlayer
    before actual AAB building (
    ./gradlew bundleRelease
    ).

    It's easier than applying lowercases (for example with Addressables package integrated).

    Result is checked via
    bundletool build-apks
    and
    unzip -vl
    on all platfroms (linux, win, osx).

    Code (CSharp):
    1.     [UnityEditor.Callbacks.PostProcessBuild]
    2.     public static void FixAndroidBuildGradleForAab(BuildTarget buildTarget, string buildPath) {
    3.         if (buildTarget != BuildTarget.Android) return;
    4.         var projectDir = Path.Combine(buildPath, PlayerSettings.productName);
    5.  
    6.         var assetsDir = Path.Combine(projectDir, "src/main/assets");
    7.         _log.Log($"collect assets: {assetsDir}");
    8.         var assetsMap = Directory.GetFiles(assetsDir, "*", SearchOption.AllDirectories)
    9.             .Select(x => x.Substring(assetsDir.Length + 1))
    10.             .ToDictionary(x => x.ToLower());
    11.  
    12.         var gradlePath = Path.Combine(projectDir, "build.gradle");
    13.         _log.Log($"fix patterns: {gradlePath}");
    14.         var content = File.ReadAllText(gradlePath);
    15.         var mo = Regex.Match(content, @"noCompress = \[(.*)\]", RegexOptions.Singleline);
    16.         var oldPatterns = mo.Groups[1].Value.Split(new[] {", "}, StringSplitOptions.None).Select(x => x.Trim('\''));
    17.         var newPatterns = oldPatterns.Select(pattern => assetsMap.TryGetValue(pattern, out var realPath) ? realPath : pattern);
    18.         var result = $"noCompress = [{string.Join(", ", newPatterns.Select(x => $"'{x}'"))}]";
    19.         _log.Log($"result replace:\n{mo.Value}\n{result}");
    20.         content = content.Replace(mo.Value, result);
    21.         File.WriteAllText(gradlePath, content);
    22.     }
    23.  
     
  5. Josep-Calull

    Josep-Calull

    Joined:
    Mar 26, 2014
    Posts:
    2
    On post build the player I does not find the directory:
    DirectoryNotFoundException: Could not find a part of the path 'C:\aab\test\test\src\main\assets'. or
    DirectoryNotFoundException: Could not find a part of the path 'C:\aab\test\test\src/main/assets'.
    Any idea?
    Thanks
     
  6. nik_d

    nik_d

    Joined:
    Apr 27, 2018
    Posts:
    60
    New Unity (>2019) exports the project to subfoler <build-path>/unityLibrary/src/main/assets
    And it's better to re-check noCompress values in new Unity.. possibly it's already fixed.
     
  7. JuliusM

    JuliusM

    Unity Technologies

    Joined:
    Apr 17, 2013
    Posts:
    551
    Unfortunately to properly fix this for both APK and AAB files, Android Gradle Plugin version 3.6 or newer is needed. Our testing has shown that this Android Gradle Plugin version has quite a few behavioural differences compared to currently used version 3.4. These differences cause quite a few projects fail to build and projects have to be modified to be able to use this new version. Because of that we have decided to not upgrade Android Gradle Plugin version to 3.6 in Unity 2019 and 2018 versions for now.
    The suggested workaround for this compression issue is still the same - use lowercase letters.
    There is also another possible solution of using a custom Android Gradle Plugin version yourself. However this is an advanced process and as mentioned before, you might have to modify your project to be able to use this version. If you want to do this, you would have to increase Android Gradle Plugin version in your project's build.gradle file and provide a custom compatible Gradle version in Unity editor preferences. Note that Android Gradle Plugin versions 3.6.0-3.6.2 are compatible with Gradle versions 5.6.4 and newer.
     
  8. nik_d

    nik_d

    Joined:
    Apr 27, 2018
    Posts:
    60
    My proveded workaround that works with any unity and any gradle version is just to generate (or fix already generated) build.gradle to refer *files in it with their real-case* instead of lower-case only.

    And even more - I think this solution is much better than depending on some new lower-case features of gradle.

    And I don't understand - why you cannot generate build.gradle in a such correct way?)
     
unityunity