I have an enterprise app which I am deploying manually (no Google Play) which uses a number of .so libraries for mapping (ArcGIS). However, the .so files (arm, armv7a, x86) in the libs folder blow the .apk size out from 3mb to 21mb. I dont particularly want to remove one of the .so files (removing support for that architecture), or mess around with one .apk per architecture.
Can anyone think of a way I can update my app without including the .so files in each update .apk?
Yes, you can have the Java portion of your app manually download the appropriate .so files into your app's internal storage folder and mark them executable.
You will then have to load them with System.load() and the full pathname of the .so file, rather than System.loadLibrary() and the trimmed library name.
The biggest issue here is that you are now responsible for matching the ABI's yourself, and more importantly, providing your own protection against being tricked into installing a modified or imposter library which might do something nefarious in the name of your app and using it's permissions.
Of course you have to make sure not to try to call any of the native methods before you have installed them.
You could also consider delivering the .so files as binary assets each in its own skeleton .apk having a shared user id (and matching certificate) as your main .apk
Or you could simply make platform-specific .apk's for each target, containing only one .so, and have your distribution system pick the right ones (though that doesn't help with the upgrade problem).
Related
I'm currently working on two different xamarin forms projects which are kind of similar though. This means that they both have mostly similar functionalities + a lot of external dependencies are the same. But I just realized that the generated .apk files are very different in size. Upon analyzing both apks with the android studio apk analyzer I found out, that the main difference between both apks lies within the "lib" folder. While one apk only contains .so files the other (bigger) one contains a lot of .dll.so files. These cause the apk to be much bigger (40MB vs 75MB).
1.) Do you have any idea why there are dll.so files in one apk but not the other?
2.) Are these dll.so files needed?
3.) If not, is there a way to get rid of these?
Application binary interface(ABI) defines how binary files (especially .so files) run on the corresponding system platform, from the instruction set used, memory alignment to the available system function library. On Android system, each CPU architecture corresponds to an ABI: armeabi, armeabi-v7a, x86, MIPs, arm64-v8a, MIPS64, x86_64.
For a mobile phone with a 64arm CPU, when it runs the app and enters libs to read the dynamic library file, it will check whether there is an arm64-v8a folder. If it didn't find arm64-v8a folder it will search for the armeabi-v7a folder and the armeabi folder, and then if the folder is not founded it will throw an exception.
I have a project with native libraries that I want to use, files with this format: lib<name>.so do get included into apk. But files with <name>.so format does not.
Is there a way to include the later type into apk in lib directory?
If not, is there a way to include the files into a directory inside apk, where I can load it from my native code?
The short answer is "no". The native binaries will only be packed into APK, and extracted to executable files upon installation, if their names follow the lib….so pattern.
Note that these libraries will be extracted to files according to the ABI of the target system. The installer does not check the actual properties of the file. The decision is based on the name of the folder under lib in the APK structure.
If you add the attribute extractNativeLibs=false to the application tag in AndroidManifest.xml of your APK, the installer (on Android Nougat and higher) will not extract the native libraries.
You can trick the system and have files that don't follow the above rule to the lib folder of APK, but there is very little sense in it, because they will never be extracted by the loader (it may also extract file gdbserver if the file is there).
The common practice is to put the arbitrary files in the assets folder of your APK, and extract them programmatically when the app runs for the first time after install. You cannot extract these files to the secured location where the usual native libraries go. You should not extract the native libraries to sdcard (e.g. getExternalFilesDir()), because the system may not allow execution of the files there, regardless of the execute access flag on the file. Make sure that you use the correct ABI flavour.
You can peek at the source code of Nougat native lib loader that can load native libraries from the APK without extraction, and use it to load your custom libraries directly from the assets folder of your APK.
I would like to inject a few dynamic resources into the assets folder of the APK. Though I'm having no luck so far.
I was trying to inject some files to the APK as a zip archive using python script using output.packageApplication.doLast, but it doesn't add the files to the APK and generates the usual apk. I've checked whether it does anything with it and surprisingly it does, but it deletes the custom files and leaves only the compiled ones.
Can anybody shed some light?
I have an NDK library that I am creating that needs to contain and access a binary data file (.dat extension). I am having trouble getting the compiled library to see this file. To make things a little more difficult, I am doing this within a library package.
I think it would work if, during my Android.mk file, I copy this .dat file to my app's resources folder, and then access that from within the app, but I feel like there must be a better way.
Any suggestions?
Instead of resources, put it in the assets folder; NDK provides API to access assets from native code.
Often, we unpack some "files" from the resources or assets to the file system (e.g. /sdcard) on the first run of the app after install. This approach works best when the files must be used by external apps and libs (e.g. to play sounds), or when these files will be changing.
Finally, you can link the data into your .so during ndk-build. This will resolve the question how the .dat file will be copied into the app folder, but reading it may be tricky, and modifying - impossible. You don't need to create a huge library. You can create a mock-up library that contains the data. If I understand correctly, you can ignore the file structure, headers, etc. You only need a file named lib something .so in your libs/armeabi (or other) folder.
is it possible to replace .so file in android app without source code?
I am creating app which use some .so files under LGPL license v2.1 http://www.gnu.org/licenses/lgpl-2.1.html
License says: "...you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it..."
Is it possible to replace .so file and recompile app without source code e.g. in existing apk? I can't give user source codes. Or some option to give user .class files so he can create apk?
Is it even possible and if so, what are options?
Thank you!
Yes, you can replace a .so file in an apk. Just use 7zip to open the apk replace the file and you are done.
About gpl: you should have 2 libraries, one so for your code and one for the code you borrowed, this way the user can replace the so for the library, but your code cannot be changed. You can also put a check for the libs version and just exit if it was changed.