I have an application that uses the Metaio SDK to show some Augmented Reality stuff.
I have an issue where the app crashes when running it on Samsung Galaxy S6. Unfortunately I don't have any logcat logs for the issue.
I found this link http://helpdesk.metaio.com/questions/46459/android-sdk-arm64-support/46479.html talking about a similar issue, it relates to the 64-bit CPU on the Samsung S6, but I'm not sure if this is the cause of my issue.
Has anyboday seen something similar to this before?
it has good chances to be related to your issue.
When you install an APK on Android, the system will look for native libraries directories (armeabi, armeabi-v7a, arm64-v8a, x86, x86_64, mips64, mips) inside the lib folder of the APK, in the order determined by Build.SUPPORTED_ABIS.
If your app happen to have an arm64-v8a directory with other libs, the 32-bit metaio libs will not be installed as the libs aren't mixed. That means you have to provide the full set of your libraries for each architecture.
So, to solve your issue, you can remove your 64-bit libs from your build, or set abiFilters to package only 32-bit architectures:
android {
....
defaultConfig {
....
ndk {
abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
}
}
}
If you get an error related to the use of the deprecated NDK support, add android.useDeprecatedNdk=true to a file named gradle.properties at the root of your project. Don't feel bad about using a deprecated integration, as using abiFilters is still the cleanest way atm to filter out 64-bit libs from an APK.
I know this is an old question and Metaio is not there anymore, but the solution was to upgrade the Metaio SDK to the latest availble version back then.
Related
For some reason my app is not 64-bit compatible.
My first thought was that it my be the lib files. I checked the resulting apk: I have arm64-v8a, armeabi, armebi-v7a, mips, x86 which all contain the same-named .so files. So, I'm thinking it is maybe because x86_64 is missing? But, I have another project running the exact same libs which IS 64-bit compatible according to the play dashboard. I can't see any difference between the two lib or gradle setups.
Has anyone encountered something similar?
UPDATE: Here is the resulting libs from analizing the apk:
Like I stated above, there are .so files for all except x86_64. Could this be the issue? Do you HAVE to have .so files for both arm64-v8a AND x86_64? And why would this not be an issue for my other projects?
Another Update:
Ok, so I THINK its not working cause I have x86 and not x86_64. Docs say " It isn't required to support every 64-bit architecture, but for each native 32-bit architecture you support you must include the corresponding 64-bit architecture." ... does this mean I can just remove x86 and it should work fine? Also, is it a good idea to remove x86? Does it remove support for many devices?
as described in official documentation
you should add ndk.abiFilters :
ndk.abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
to you app build.gradle file
Ok so I figured it out.
It seems that I managed to 'trick' google into thinking my apps were 64-bit compatible. Just because the x86_64 FOLDER was available, I guess the google console assumed it contained the required libraries. The problem was that the x86_64 libs were missing. My solution, though not ideal, was to remove the x86 libraries (small percentage of device support anyway) so that I don't need x86_64.
SO, yay :) all my apps are now 64-bit compliant (although I've lost SOME device support).
According to https://android-developers.googleblog.com/2017/12/improving-app-security-and-performance.html:
In August 2019, Play store will require that new apps and app updates with native libraries provide 64-bit versions in addition to their 32-bit versions.
I have a React Native application (which includes native code). My question is how can I know whether a third party library I'm using or even my own code is not supporting 64-bit? And how can I fix it?
Update
I added x86_64 to my build.gradle and I now see the x86_64 folder in the apk but I think some of the files are missing.
Here is, how my x86 folder looks like:
And here is how my x86_64 folder looks like:
React Native will support 64 bit for android starting version 0.59
https://github.com/facebook/react-native/issues/2814#issuecomment-457688789
https://github.com/facebook/react-native/commit/f3e5cce4745c0ad9a5c697be772757a03e15edc5
All of the native code for an app is stored in the libs/ directory in the root of the apk. eg for compiled ARM or x86 code, you can find it in libs/architecture_type/lib_name.so.
An APK is essentially just a zip file so you can extract it with any zip tool.
The list of architectures (ABIs) is here. If you don't have directories for arm64-v8a or have x86 but don't have x86_64 then you are missing the 64 bit native code.
https://github.com/facebook/react-native/issues/2814
Facebook seems to be dragging their feet on supporting 64 bit builds.
You can check the intermediates in the build folder to see what abis you are supporting.
https://developer.android.com/ndk/guides/abis.html
Android takes the lowest common denominator of build abi. This is going to become an issue if Facebook doesn't address it soon.
React native has been released the new version of the react native on 12 march.
In this new version react native support the 64 bit systems.
You can read more detail about this on below link.
http://facebook.github.io/react-native/blog/2019/03/12/releasing-react-native-059
react-native new versions support 64 bit automatically.
just update react-native version to 0.59.0 or after and rebuild your application, just run:
react-native upgrade 0.59.1
If you are using react native version less than 0.59 then you must upgrade your apps to react native 0.59 or higher. React native supports 64 bit only from 0.59 version.
Also, make sure your app has following lines in your MyProject/Android/App/Build.gradle file.
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk true // If true, also generate a universal APK
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
}
}
For more refer:
Update your React Native Apps to be 64 Bit
I've attempted the solution outlined in building-combined-armv7-x86-apk-after-crosswalk-integration-in-an-ionic-project.
The great thing is that it creates a single apk file. But when I run my cordova application, I get the following alert:
Mismatch of CPU Architecture
The Crosswalk Project Service must be updated to match the CPU architecture of the device. Please install it from the app store, then restart app.
Looks like Crosswalk is not embedded in the combined apk.
Does anyone know how to embed Crosswalk in a combined apk?
After I had spent a lot time looking for I solved it:
If you open the ".apk" file generated with a compressor (like WinRar), inside folder "lib" you are going to see folders for different architectures (x86_64, x86, mips64, mips, armeabi-v7a, armeabi and arm64-v8a in my case). After inspect all them only x86 and armeabi-v7a have "libxwalkdummy.so" and "libxwalkcore.so" files, so I deleted which ones do not have it. So "lib" folder will only contain x86 and armeabi-v7a folders.
After that it seems that app works with crosswalk embedded.
I have a few native libraries that are fairly big and bloating the application binary size. I looked into APK splitting but maintaining and QAing multiple APKs is not something I want to do.
So I'd like to exclude unused architectures in my release build flavour using the ndk.abiFilters Gradle property. (The debug builds I want to leave alone so that I can run the HAXM-accelerated emulator on x86).
I was thinking of just having armeabi-v7a and arm64-v8a in my release flavour, but I'm not sure whether it is worth worrying about the market share of the other architectures I'm dropping. After a lot of looking around I cannot find any reference to market share of ARMv6 (armeabi), MIPS, x86 or x86_64. My intuition tells me that the latter three are almost non-existent, but I'm not sure about ARMv6.
I found this link on a forum that has a list of phones that use various architectures. Is there something more reliable somewhere? Maybe with % of users similar to the Android version dashboard?
Anything else I may miss if I just build my native libs for armeabi-v7a and arm64-v8a (or armeabi, armeabi-v7a and arm64-v8a)?
First off, if you're worring about binary size, you don't really need arm64-v8a, all those devices can run the armeabi-v7a binaries just fine. Only if you really need to cram the last extra performance out of it, it might be worthwhile.
As for armeabi and ARMv6; Android itself doesn't officially support it any longer, since Android 4.4 (October 2013) - and since Android 4.0 it should be much less common (from that version, AOSP source requires modifications to still build for ARMv6). So in practice, if you aren't supporting versions below 4.4, you can drop that one without any significant loss.
Also, for x86; many of those devices ship with surprisingly decent emulation of arm binaries, so those can manage with the armeabi-v7a version just fine as well.
EDIT: The above was written in 2015; these days Play Store requires that apps include support for arm64-v8a. But these days the next question is more about whether you need to include armeabi-v7a at all, or if the market share of 32 bit devices is small enough to drop support for.
Including additional architectures will no longer have any impact on the binary size when using app bundles, as in that case Google Play will serve each device only the binaries that apply to that particular device. Not only that, but also application updates will be way smaller and faster.
Leaving the previous information for projects still not using app bundles:
Unfortunately, the Android Dashboard, as useful as it is, does not provide architecture information, nor does Google Analytics.
The Unity statistics used to provide statistics per architecture and CPU features. Note, however, that these are not general statistics, but only cover users of Unity applications/games. The information doesn't seem to be available in a public link anymore, so I have replaced the direct links with the latest snapshots in archive.org.
I was stuck with this problem when using Mapbox, then later found this article which was very useful.
Based on the below picture you just need armeabi-v7a and x86. Then based on Jose Gómez answer, I only added armeabi-v7a and didn't have any problem at all.
So add this line to your app.gradle
android {
defaultConfig {
//other configs
ndk {
abiFilters "armeabi-v7a"
}
}
}
If you're still worried about 2% - 3% of those who use x86 architecture, like ASUS ZenFone and lenovo phones then use this config instead in app.gradle
ndk {
abiFilters "armeabi-v7a", "x86"
}
Also for genymotion emulators you should use x86 architecture
UPDATE
If you get this error while publishing the apk in play store
Then use this
ndk {
abiFilters "armeabi-v7a", "arm64-v8a"
}
And finally, I suggest you use app bundle for releasing the APK
When I read #mstorsjo answer I was a little bit confused how to really use only one (or two) native libs, even though it's quite simple and straightforward. Therefore, I will give here an example and some more explanation (based on my further research).
For each supported architecture we have to create a specific folder in the jniLibs folder and drop the .so file there. As an example, for supporting armeabi-v7a (32bit) and arm64-v8a (64bit):
|--app
|--|--src
|--|--|--main
|--|--|--|--jniLibs
|--|--|--|--|--armeabi-v7a
|--|--|--|--|--|--.so Files
|--|--|--|--|--arm64-v8a
|--|--|--|--|--|--.so Files
With armeabi-v7a you support more than 90% of the available devices, but since it is 32bit architecture, running it on 64bit devices will result in an loss of performance (20-30%) {1}. For each specific case it can be quite handy to check the actual amount of supported devices, which can be done within the Google Play Console in the Release management > Device catalog section, by specifying ABI as filter.
Attention
When you don't add binaries for all architectures you have to be aware of the following:
If your app contains any other native libraries, you'll have to make sure you only have the same versions of them as well. That is due to Android demanding that all loaded native libraries be built for the same architecture. For example, if the first native library loaded is armeabi-v7a, Android will look ONLY for armeabi-v7a libraries on all System.loadLibrary() calls after that. If it doesn't find that exact architecture, it'll throw the java.lang.UnsatisfiedLinkError exception. {1}
I ran into this problem because some of my dependencies used native libraries, whereby armeabi-v7a couldn't be loaded anymore.
In my product I'm finding that when I install the APK file onto the Galaxy Nexus running android 4.0.1 the incorrect .so file is being installed. I have a so-called "fat" APK that includes native code for armeabi, armeabi-v7a and x86.
I'm finding that the .so file for the armeabi CPU ABI is being extracted from the APK file rather than the armeabi-v7a .so file. If I remove the "armeabi" folder from the APK file then the galaxy nexus correctly installs the .so file from the armeabi-v7a folder.
I've verified that the CPU ABI of the nexus is "armeabi-v7a" and its secondary ABI is "armeabi".
Has anyone else seen this problem, and have they found a way to work around the issue without removing the "armeabi" folder from their libs directory in the APK?
This seems to be a bug. I've tested it also by creating a small project using native code and indeed Galaxy Nexus chooses the wrong library (armeabi instead of armeabi-v7a).
I've reported this bug at http://code.google.com/p/android/issues/detail?id=25321 , with the sample project attached on the bug. Please star it to bring attention to Android engineers.
Seems that another StackOverflow question originates from this bug too: Android floating point math performance.