Blame view

3rdparty/c-ares-1.18.1/docs/ares_library_init_android.3 5.1 KB
73ef4ff3   Hu Chunming   提交三方库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
  .\"
  .\" Copyright (C) 2017 by John Schember
  .\"
  .\" Permission to use, copy, modify, and distribute this
  .\" software and its documentation for any purpose and without
  .\" fee is hereby granted, provided that the above copyright
  .\" notice appear in all copies and that both that copyright
  .\" notice and this permission notice appear in supporting
  .\" documentation, and that the name of M.I.T. not be used in
  .\" advertising or publicity pertaining to distribution of the
  .\" software without specific, written prior permission.
  .\" M.I.T. makes no representations about the suitability of
  .\" this software for any purpose.  It is provided "as is"
  .\" without express or implied warranty.
  .\"
  .TH ARES_LIBRARY_INIT_ANDROID 3 "13 Sept 2017"
  .SH NAME
  ares_library_init_android \- c-ares library Android initialization
  .SH SYNOPSIS
  .nf
  #include <ares.h>
  
  int ares_library_init_android(jobject \fIconnectivity_manager\fP)
  
  int ares_library_android_initialized();
  
  void ares_library_init_jvm(JavaVM *\fIjvm\fP)
  
  .fi
  .SH DESCRIPTION
  The \fIares_library_init_android(3)\fP function performs initializations
  internally required by the c-ares library when used on Android. This can take
  place anytime after \fIares_library_init(3)\fP. It must take place after
  \fIares_library_init_jvm\fP. ares_library_init_android must be called before
  DNS resolution will work on Android 8 (Oreo) or newer when targetSdkVersion 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
  Connectivity 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 targeted Android version.
  
  Deinitialization will take place though \fIares_library_cleanup(3)\fP.
  
  The \fBares_library_init_jvm\fP 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
  \fIares_library_init_android(3)\fP. This must be call before
  \fIares_library_init_android(3)\fP.
  
  The \fBares_library_android_initialized\fP function can be used to check
  whether c-ares has been initialized for use with Android.
  .SH RETURN VALUES
  ARES_SUCCESS will be returned on success otherwise an error code will be
  returned.
  .SH THREAD SAFETY
  .B 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 conditions 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.
  .SH JNI
  Accessing the Connectivity Manager though Java:
  
  Register the \fIares_library_android_init\fP.
  .nf
    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;
    }
  .fi
  Calling the registered function from Java:
  .nf
    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));
      }
    }
  .fi
  Initializing the Connectivity Manager in JNI directly using an Android
  Context. It is assumed the JVM has aleady been registered through
  \fIJNI_OnLoad\fP.
  .nf
    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);
    }
  .fi
  .SH AVAILABILITY
  This function was first introduced in c-ares version 1.15.0.
  .SH SEE ALSO
  .BR ares_library_init(3),
  .BR ares_library_cleanup(3),
  .SH AUTHOR
  John Schember
  .PP
  Copyright (C) 2017 by John Schember