Android Studio NDK issue - android

I have a problem. I have an app which works fine on Android 5 & 6. The app has c++ shared lib refference. The problem is: When I compile and assembling to .apk without selecting my 4.0.3 device as target for execution then after installing its failing in my native code. But when Im trying to address this issue via debug everything works just fine. Is it possible that Android Studio is adding some additional parameters to build configuration without which app wont run.
Thank you.

I've found out that the problem is with my lz4 implementation which several years ago I've taken from windows app. There was a lot if stuff like:
#define U32 uint32_t
void* source = {some void pointer}
void* destination = {some void pointer}
*(U32*)destination = *(U32*)source;
I've found on internet implementation of lz4 for Androin and noticed that the differens is in using memcpy not (U32) = (U32). I have rewritten my code to exclude all places like this and it started to work on my 4.0.3.

Related

Unity: DllNotFoundException (Unity 2018.2; Android)

I have an Android native library (C++ code base) called:
libserverapp.so
And I cannot get the Android build to find it:
"DllNotFoundException: serverapp"
I am using an internal build system, but when I parse the output of the build process, I can see many calls of the form:
android-ndk/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/arm-linux-androideabi-g++.exe -march=armv7-a
After building my Android app, I inspect the resulting APK (renaming to .zip and extracting), and can see my library file here:
lib/armeabi-v7a/libserverapp.so
I can confirm that "ARMv7" is the target architecture in the Android Player settings, and I access the library, in C#, via:
[DllImport("serverapp", CallingConvention = CallingConvention.Cdecl)]
private static extern void run_sim(StringBuilder matchInput, StringBuilder results, int randomSeed);
I have built a Windows DLL of the C++ code, to use in the Editor, and everything works great. However, when I move to Android, the .so cannot be found. The import settings for libserverapp.so are:
Platform: Android; CPU: ARMv7; Path: Assets/Plugins/Android/libserverapp.so; Type: Native
Given that the final APK includes the .so where I expect it to be (lib/armeabi-v7a/), I assume my Unity settings are correct? Also, I am not using IL2CPP for the Android build.
Finally, when I do an object dump of the library file (using arm-linux-androideabi-objdump.exe), the file format of the library file is "elf32-littlearm".
I feel that the issue here is simply finding the .so, not the functionality within it. Any ideas on what's going on here?
Thanks!
I ended up solving the problem. I mentioned that was using an internal build system. Well, there seems to be a bug in it. I ported things over to official Android NDK makefiles, and then it "just worked". So in this case, the library could be found, but its contents weren't valid.

Cross-compiling of C code for Android

I cross-compiled my C application for Android ARM with arm-linux-gnueabi tool under Ubuntu 16.04 LTS. I compiled it with static linking flag. This C application is big and it has complicated makefile. It compiled successfully without any errors. But it behaves differently on Android phone and Ubuntu PC. More precisely i have two problems:
popen() and system() functions don't work on Android. They are carried out but do nothing and don't give any errors. This problem i solved with dirty hack.
fgets() functions works strange on Android.
1. About first problem.
I did small research and found that Android doesn't use ordinary libc library (glibc or another library which implements POSIX standard properly). It uses Bionic library instead of it (sorry, Android is new OS for me). I looked into popen() and system() functions code and noticed that these functions use _PATH_BSHELL macros. _PATH_BSHELL is path to the actual system shell. This path is "/system/bin/sh" on Android and "/bin/sh" on Ubuntu.
When i understood it i tried to hook popen() and system() functions. I copied code of these functions from the Bionic source, than i defined macros #define _MY_PATH_BSHELL "/system/bin/sh" and replaced calls like execve(_MY_PATH_BSHELL, argp, environ); by execve(_MY_PATH_BSHELL, argp, environ); calls. So it started work properly.
2. About second problem.
On Ubuntu this code works properly:
is_received = false;
while(!is_received) {
FILE *cmd = popen(command, "r");
is_received = fgets(buf, sizeof(buf), cmd) == NULL ? false : true;
}
But on Android fgets() always returns NULL and this loop works infinitely long. I tried to use read() function instead of fgets() and it worked.
On Android this code with read() works properly:
is_received = false;
while(!is_received) {
FILE *cmd = hooked_popen(command, "r");
int fd = fileno(cmd);
is_received = read(fd, buf, sizeof(buf)) == 0 ? false : true;
}
My questions.
How to solve my problems with popen() and system() neatly and correctly? I think i have to link statically with Bionic library. Is it right? How can i do it in console without Android Studio? I read that it is necessary to use NDK but it is not clear to me how.
Why fgets() behavior isn't similar on Android and Ubuntu?

too many libraries when loading error, Chromium compile for Android4.2.2

I followed this to compile Chromium ( Actually I need content_shell_apk):
https://www.chromium.org/developers/how-tos/android-build-instructions
Compilation of both ChromePublic.APK and ContentShell.apk succefull, but when I run them in my Android 4.2.2 device, I get this error:
https://paste2.org/nxFYVvtW
Cannot load library: soinfo_alloc(linker.cpp:287): too many libraries when loading "libEGL_mali.so"
I am searching for 2 days, and only thing I could find is this:
comments.gmane.org/gmane.comp.web.chromium.devel/43328
How should I get rid of this error, and compile official ContentShell.apk for my device?
The issue is resolved. Somehow, my out/Default directory was corrupted.
I removed that directory, and run GN configuration again:
gn args out/Default
At this point, to make sure that there are no any debug symbols included:
target_os = "android"
target_cpu = "arm"
is_debug = false
is_component_build = false
is_clang = true
symbol_level = 1
After that, generated filesize for ContentShell.apk is around 40Mbytes ( Jan.2017 ), and it runs perfectly on Android 4.2.2 .
To be able to modify user interface, someone can edit shell_view.xml which is at:
./content/shell/android/java/res/layout/shell_view.xml
There are also a few java files, which can be edited easily, and make your own browser for your custom android device :)
Many thanks to people at #chromium for IRC help.

Boost.Asio on Android failing with Service Not Found (Boost 1.53; NDK r8e)

I am trying to build a cross-platform application for Android and iOS and have chosen to use Boost to simplify communication and to parse the JSON from the response. Everything works fine in iOS, but Android fails with "service not found" error, or "host not found (authoritative)" if I change the query to query(server, "");.
I pulled the code out of my application and simplified it to what was throwing the error and this is what I have:
...
#include <boost/asio.hpp>
boost::asio::io_service io_service;
std::string server = "<server_address>";
// Get a list of endpoints corresponding to the server name.
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query(server, "http");
boost::system::error_code ec;
boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query,ec);
if (ec)
{
return env->NewStringUTF(ec.message().c_str());
}
I am using Android NDK r8e (64-bit) and Boost version 1.53 (latest releases as of writing). I have used https://github.com/MysticTreeGames/Boost-for-Android with slight modification to work with the 64-bit NDK (see https://github.com/MysticTreeGames/Boost-for-Android/pull/28) for building the required Boost libraries.
I will be modifying this to work with async_resolve, which is what the iOS version is using, once I can get this part working.
Edit:
I noticed I had forgotten to update the Android Manifest file, so I added
<uses-permission android:name="android.permission.INTERNET"></uses-permission>, but I still get the same errors. Am I simply missing something else in the manifest?
It means that the OS can't figure out which port stands for http. On most POSIX-compliant systems this mapping is done in /etc/services file, and if http line is missing there, you'll get "service not found" error.
I don't know whether Android has this file or not (older versions didn't support it at all, the services were hardcoded in bionic), but if you get the above error, the only workaround is to set the desired port manually:
tcp::resolver::query query(tcp::v4(), yourHost, "80");

Pusher not working on Phonegap for Android

I'm facing a problem and would really appreciate your help...
Android SDK: 4.0
Phonegap: 1.8.1
Pusher: 1.12
I have created an Android project using Phonegap that needs to receive server notifications through Pusher.
I'm running it in Eclipse and AVD emulator, but the problem is that every time I try to establish a connection to pusher, I get an Unavailable state from the bind to state_change.
I have tested the connection to Internet in the emulator browser and it works fine. I have also tested that the server is responding and that the Pusher key is the right one by testing my code on Firefox.
This are the steps I have followed:
I have included the WebSocket.java and WebSocketFactory.java files in the src folder.
I have included websocket.js file in my js folder and included a reference in the index.html file.
I have included a reference to http://js.pusher.com/1.12/pusher.js in the index file.
I have included the following line in my Android App.java file: this.appView.addJavascriptInterface(new WebSocketFactory(this), "WebSocketFactory");
This is the code I'm using to connect to Pusher:
// Connect
var pusher = new Pusher(CONFIG.PUSHER.APP_KEY);
pusher.connection.bind('state_change', connectionStateChange);
function connectionStateChange(state) {
alert(state.current);
}
Is there something I'm missing? Any ideas on why the connection is not working or about where to check?
Thanks for your help.
Chadid
For version 2.x of pusher-js and above the library will work within PhoneGap without any additional requirements or setup. Simply include the library and use it - no need for WebSocket.java or WebSocketFactory.java.
For version 1.x this blog post and associated code demonstrates how to get Pusher working on PhoneGap:
http://blog.pusher.com/2012/7/5/pusher-on-phonegap-for-android

Categories

Resources