1ARES_LIBRARY_INIT_ANDROID(3)Library Functions ManualARES_LIBRARY_INIT_ANDROID(3)
2
3
4
6 ares_library_init_android - c-ares library Android initialization
7
9 #include <ares.h>
10
11 int ares_library_init_android(jobject connectivity_manager)
12
13 int ares_library_android_initialized();
14
15 void ares_library_init_jvm(JavaVM *jvm)
16
17
19 The ares_library_init_android function performs initializations inter‐
20 nally required by the c-ares library when used on Android. This can
21 take place anytime after ares_library_init(3). It must take place after
22 ares_library_init_jvm. ares_library_init_android must be called before
23 DNS resolution will work on Android 8 (Oreo) or newer when targetSd‐
24 kVersion is set to 26+.
25
26 As of Android 8 (API level 26) getting DNS server information has
27 becomei more restrictive and can only be accessed using the Connectiv‐
28 ity Manager. It is necessary to pass the connectivity manager to c-ares
29 via JNI. Also, the ACCESS_NETWORK_STATE permission must be present in
30 the Android application.
31
32 Android older than 8 do not need to to be initalized as they are less
33 restrictive. However, this is a run time not compile time limitation.
34 Proper Android initalization should take place regardless of the tar‐
35 geted Android version.
36
37 Deinitalization will take place though ares_library_cleanup(3).
38
39 The ares_library_init_jvm function allows the caller to register the
40 JVM with c-ares. It's meant to be called during JNI_OnLoad because
41 you're guaranteed to have the JVM in that function. The JVM is required
42 in order to use the Connectivty Manager registered using
43 ares_library_android_init. This must be call before
44 ares_library_android_init.
45
46 The ares_library_android_initialized function can be used to check
47 whether c-ares has been initalized for use with Android.
48
50 ARES_SUCCESS will be returned on success otherwise an error code will
51 be returned.
52
54 These init functions are not thread safe. You have to call it once the
55 program has started, but this call must be done before the program
56 starts any other thread. This is required to avoid potential race con‐
57 ditions in library initialization, and also due to the fact these might
58 call functions from other libraries that are thread unsafe, and could
59 conflict with any other thread that is already using these other
60 libraries.
61
63 Accesing the Connectivity Manager though Java:
64
65 Register the ares_library_android_init.
66
67 static JNINativeMethod funcs[] = {
68 { "initialize_native", "(Landroid/net/ConnectivityManager;)I",
69 (void *)&ares_library_init_android}
70 };
71
72 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
73 {
74 JNIEnv *env = NULL;
75 jclass cls = NULL;
76 jint res;
77
78 if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6) != JNI_OK)
79 return -1;
80
81 cls = (*env)->FindClass(env, JNIT_CLASS);
82 if (cls == NULL)
83 return -1;
84
85 res = (*env)->RegisterNatives(env, cls, funcs,
86 sizeof(funcs)/sizeof(funcs[0]));
87 if (res != 0)
88 return -1;
89
90 ares_library_init_jvm(vm);
91 return JNI_VERSION_1_6;
92 }
93
94 Calling the registered function from Java:
95
96 public class MyObject {
97 static {
98 System.loadLibrary("cares");
99 }
100
101 private static native boolean initialize_native(ConnectivityManager
102 connectivity_manager);
103
104 public static boolean initialize(Context context) {
105 initialize_native((ConnectivityManager)context.getSystemSer‐
106 vice(Context.CONNECTIVITY_SERVICE));
107 }
108 }
109
110 Initalizing the Connectivity Manager in JNI directly using an Android
111 Context. It is assumed the JVM has aleady been registered through
112 JNI_OnLoad.
113
114 void initialize(jobject android_context)
115 {
116 jclass obj_cls = jni_get_class(env, "android/content/Context");
117 jmethodID obj_mid = jni_get_method_id(env, obj_cls, "getSystemSer‐
118 vice", "(Ljava/lang/String;)Ljava/lang/Object;");
119 jfieldID fid = (*env)->GetStaticFieldID(env, obj_cls, "CONNECTIV‐
120 ITY_SERVICE", "Ljava/lang/String;");
121 jstring str = (*env)->GetStaticObjectField(env, obj_cls, fid);
122 connectivity_manager = (*env)->CallObjectMethod(env, android_con‐
123 text, obj_mid, str);
124 if (connectivity_manager == NULL)
125 return;
126 ares_library_init_android(connectivity_manager);
127 }
128
130 This function was first introduced in c-ares version 1.14.0.
131
133 ares_library_init(3), ares_library_cleanup(3),
134
136 John Schember
137
138 Copyright (C) 2017 by John Schember
139
140
141
142
143 13 Sept 2017 ARES_LIBRARY_INIT_ANDROID(3)