Old Android version, linux shared library and apk packer controlled by Android Studio

  1. Old Android version (4.4 on my side) didn’t look for shared library by SONAME inside. It only checks file name. For example, in recent Android version (7 or 8), one file named libcrypto.so whose SONAME is libcrypto.so.1.0.0 can be loaded by dependents successfully. But in old versions the system reported “dlopen failed to load libcrypto.so.1.0.0”.
  2. In Linux’s programming conventions, a shared library usually has name like libxxxx.so.x.y.z and a symbolic link named libxxxx.so would also be created pointing to the former. That’s OK in a normal Linux system, but has problems with Android’s app.  The android apk’s zip format didn’t recognize symbolic link, and as I described in 1. it also didn’t load shared library by  SONAME.
  3. Android Studio integrated CMake to build native libraries and it also packs what generated by CMake (app/build/intemediates/cmake/<debug-or-release>/obj/<arch>)/) to libs directory inside the apk. That’s good. But! But it packs only files with .so extension. So, files like libxxxx.so.x.y.z would be packed into the apk, and we don’t have any configurable option on both gradle file and CMakefile.txt to add them manually.

Android SurfaceView: can be used for media or direct access, but not for both.

That is, if you have an instance of SurfaceView, you can use it for video/camera, or use it for direct access as a buffer, but you cannot reuse it for media after you already accessed it through either ANativeWindow API or any other internal ways.

The reason is in ASOP code Surface.cpp. Surface connected to CPU if it once got locked, which is a necessary step to access its internal buffer. But it only got disconnected in  destructor. On other side, if you bind the Surface to media, it checks the connection status and return an error when it found it has already been connected to CPU.

So, if you need a SurfaceView for both purpose, you have to destroy the old, assuming it is for direct access, and create a new one for media.

So many traps there…

Simply, a .so compiled by android ndk r9 gcc 4.6 crashed on loading in function __check_for_sync8_kernelhelper.

After looking up the issue in Google, I found this issue has been reported to Google: https://code.google.com/p/android/issues/detail?id=58476. Unfortunately no solution at present.

Basically it is an libgcc issue depending on linux kernel version. Lower kernel version lacks the symbol that libgcc in 4.6 or higher needs. For example, the Galaxy Nexus I am just testing app on.

 

So,

1) Avoid using 64bit atomic operation built in gcc, if you can control everything in your codes.

2) Using gcc 4.4.3. For ndk r9 there is a legacy toolchain package in a separated download link.