Titanium JIRA Archive
Appcelerator Community (AC)

[AC-6485] Reducing APK size

GitHub Issuen/a
TypeBug
Priorityn/a
StatusClosed
ResolutionNot Our Bug
Resolution Date2020-03-03T16:01:48.000+0000
Affected Version/sn/a
Fix Version/sn/a
Componentsn/a
Labelsn/a
ReporterRainer Schleevoigt
AssigneeJoshua Quick
Created2020-02-07T18:37:23.000+0000
Updated2020-03-03T16:01:48.000+0000

Description

I have added ffmpeg to an app by using a new module. This module uses a multi architect binary. It is very large (ca. 20MB). After building of app (apk) I see with a debug tool: the binaries are twice in the apk: first under /assets and second under /assets/Resources/ I guess the system uses only one place. Which binary I can remove and why the asset has this two places?

Comments

  1. Joshua Quick 2020-02-08

    I'm not really sure what you're doing. If the module is open source, then perhaps you can point us to what it looks like? The only thing that gets duplicated by a module are files you put under its "assets" folder. These files are added to APK "assets" and as JAR resources. Unfortunately, devs are using it for both purposes and we don't want to break it. In Titanium 9.0.0, we'll be offering a new "Resources" folder which will only add files to APK "assets/Resources".
       <module>/android/assets
       
    If your module includes prebuilt C/C++ \*.so libraries, then they need to go under the following architecture folders. I imagine this is what you want. When you do an app build, it'll copy the \*.so libraries to similar folders within the APK, which is where they're supposed to go.
       <module>/android/libs/arm64-v8a
       <module>/android/libs/armeabi-v7a
       <module>/android/libs/x86
       
  2. Rainer Schleevoigt 2020-02-10

    In case of ffmpeg the module uses binaries (not *.so). During first run the right binary will copied (and unzipped) and make executable in data folder. In the compiled apk I see the ffmpeg (zipped) binaries in folder /assets *and* in folder /assets/Resources. https://github.com/AppWerft/Ti.FFmpeg/ I guess I can rewmove the version under /assets/Resources. Right?
  3. Joshua Quick 2020-02-11

    If I understand correctly, your module project has binaries under the following directory. If this is the case, then yes, it will duplicate the files.
       <module>/android/assets
       
    What you can do instead is move your binaries to the below folder. This folder copies files to APK "assets" as well and it won't duplicate the files. This is supported by all Titanium SDK versions. I don't think this folder is documented, but it's what our "appcelerator.encrypteddatabase" module uses and we need to maintain backward compatibility. Also note that this copies files to the root "assets" folder in the APK. If you want the files to be accessible to Titanium's JavaScript code, you'll need to put your binaries under a "Resources" subdirectory (which I think you already know).
       <module>/android/platform/android/bin/assets
       
    Does this help?
  4. Rainer Schleevoigt 2020-02-11

    Maybe it helps. With the module Kroll method loadBinaries() binaries will copied from folder addressed by getFilesDirectory(), this is the assets folder directly underneath the module folder. How can I address /android/platform/android/bin/assets? Here the copy process: https://github.com/AppWerft/Ti.FFmpeg/blob/master/android/src/com/github/hiteshsondhi88/libffmpeg/FileUtils.java#L54-L87 Although the apk is zipped the zipping of ffmpeg with zip -9 saves 10MB. I guess it is due the other zip metric of zipalign?
  5. Rainer Schleevoigt 2020-02-11

    Ah I understand: I have only to move the architecture folder structure to /android/platform/android/bin/assets. In the end the binaries are in the same folder, I don't have to modify the copy code.
  6. Rainer Schleevoigt 2020-02-11

    It works! old apk size 97MB, new 57MB. Maybe I can remove the x86 variant. It is not possible to deliver apks depending on architecture. I can deploy 64bit one, but the 32bit only will rejected.
  7. Joshua Quick 2020-02-11

    I recommend that you support all architectures in the module and let the app decide which architectures to support. In the "tiapp.xml", you can configure which architectures you want as follows. In you
       <ti:app xmlns:ti="http://ti.appcelerator.org">
       	<android>
       		<!-- All architectures supported by Titanium 7.0.0 to 8.x.x. -->
       		<!-- <abi>armeabi-v7a,arm64-v8a,x86</abi> -->
       
       		<!-- All architectures supported by Titanium 9.0.0 and higher. -->
       		<!-- <abi>armeabi-v7a,arm64-v8a,x86,x86_64</abi> -->
       
       		<!-- This is what you want. -->
       		<abi>armeabi-v7a,arm64-v8a</abi>
       	</android>
       </ti:app>
       
    Also note that "production" builds exclude x86 by default since it's really only relevant to the emulator. Titanium only adds x86 to APKs when doing test/development builds by default, unless you configure it via your "tiapp.xml" as shown above.

JSON Source