ares_library_init_android - ares library Android initialization
#include <ares.h> int ares_library_init_android(jobject connectivity_manager) int ares_library_android_initialized(); void ares_library_init_jvm(JavaVM *jvm)
Library Functions Manual ARES_LIBRARY_INIT_ANDROID(3)
NAME
ares_library_init_android - c-ares library Android initialization
SYNOPSIS
#include <ares.h>
int ares_library_init_android(jobject connectivity_manager)
int ares_library_android_initialized();
void ares_library_init_jvm(JavaVM *jvm)
DESCRIPTION
The ares_library_init_android(3) function performs initializations
internally required by the c-ares library when used on Android. This
can take place anytime after ares_library_init(3). It must take place
after ares_library_init_jvm. ares_library_init_android must be called
before DNS resolution will work on Android 8 (Oreo) or newer when tar-
getSdkVersion is set to 26+.
As of Android 8 (API level 26) getting DNS server information has
becomei more restrictive and can only be accessed using the Connectiv-
ity Manager. It is necessary to pass the connectivity manager to c-ares
via JNI. Also, the ACCESS_NETWORK_STATE permission must be present in
the Android application.
Android older than 8 do not need to to be initialized as they are less
restrictive. However, this is a run time not compile time limitation.
Proper Android initialization should take place regardless of the tar-
geted Android version.
Deinitialization will take place though ares_library_cleanup(3).
The ares_library_init_jvm function allows the caller to register the
JVM with c-ares. It's meant to be called during JNI_OnLoad because
you're guaranteed to have the JVM in that function. The JVM is required
in order to use the Connectivty Manager registered using
ares_library_init_android(3). This must be call before
ares_library_init_android(3).
The ares_library_android_initialized function can be used to check
whether c-ares has been initialized for use with Android.
RETURN VALUES
ARES_SUCCESS will be returned on success otherwise an error code will
be returned.
THREAD SAFETY
These init functions are not thread safe. You have to call it once the
program has started, but this call must be done before the program
starts any other thread. This is required to avoid potential race con-
ditions in library initialization, and also due to the fact these might
call functions from other libraries that are thread unsafe, and could
conflict with any other thread that is already using these other
libraries.
JNI
Accessing the Connectivity Manager though Java:
Register the ares_library_android_init.
static JNINativeMethod funcs[] = {
{ "initialize_native", "(Landroid/net/ConnectivityManager;)I",
(void *)&ares_library_init_android}
};
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
JNIEnv *env = NULL;
jclass cls = NULL;
jint res;
if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6) != JNI_OK)
return -1;
cls = (*env)->FindClass(env, JNIT_CLASS);
if (cls == NULL)
return -1;
res = (*env)->RegisterNatives(env, cls, funcs, sizeof(funcs)/sizeof(funcs[0]));
if (res != 0)
return -1;
ares_library_init_jvm(vm);
return JNI_VERSION_1_6;
}
Calling the registered function from Java:
public class MyObject {
static {
System.loadLibrary("cares");
}
private static native boolean initialize_native(ConnectivityManager
connectivity_manager);
public static boolean initialize(Context context) {
initialize_native((ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE));
}
}
Initializing the Connectivity Manager in JNI directly using an Android
Context. It is assumed the JVM has aleady been registered through
JNI_OnLoad.
void initialize(jobject android_context)
{
jclass obj_cls = jni_get_class(env, "android/content/Context");
jmethodID obj_mid = jni_get_method_id(env, obj_cls, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
jfieldID fid = (*env)->GetStaticFieldID(env, obj_cls, "CONNECTIVITY_SERVICE", "Ljava/lang/String;");
jstring str = (*env)->GetStaticObjectField(env, obj_cls, fid);
connectivity_manager = (*env)->CallObjectMethod(env, android_context, obj_mid, str);
if (connectivity_manager == NULL)
return;
ares_library_init_android(connectivity_manager);
}
AVAILABILITY
This function was first introduced in c-ares version 1.15.0.
ATTRIBUTES
See attributes(7) for descriptions of the following attributes:
+---------------+------------------+
|ATTRIBUTE TYPE | ATTRIBUTE VALUE |
+---------------+------------------+
|Availability | library/libcares |
+---------------+------------------+
|Stability | Volatile |
+---------------+------------------+
SEE ALSO
ares_library_init(3), ares_library_cleanup(3),
AUTHOR
John Schember
Copyright (C) 2017 by John Schember
NOTES
Source code for open source software components in Oracle Solaris can
be found at https://www.oracle.com/downloads/opensource/solaris-source-
code-downloads.html.
This software was built from source available at
https://github.com/oracle/solaris-userland. The original community
source was downloaded from https://c-ares.haxx.se/download/c-
ares-1.17.2.tar.gz.
Further information about this software can be found on the open source
community website at https://c-ares.haxx.se/.
13 Sept 2017
ARES_LIBRARY_INIT_ANDROID(3)