1 # This file is part of NIT (http://www.nitlanguage.org).
3 # Copyright 2012-2014 Alexis Laferrière <alexis.laf@xymus.net>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 # Java related services specific to Android and its Dalvik VM
23 # Main Java Activity of this application
25 # Require: A Nit activity is currently running.
26 fun native_activity
: NativeActivity is abstract
28 # Current reference context, either an activity or a service
29 fun native_context
: NativeContext do return native_activity
34 # We cannot create a JVM on Android
36 # This method is not reachable on this platform anyway.
37 # `Sys::jvm` is implemented by the main activity modules.
38 redef fun create_default_jvm
do abort
40 redef fun jni_env
do return jvm
.attach_current_thread
42 private var class_loader
: nullable JavaObject = null
44 private var class_loader_method
: nullable JMethodID = null
46 redef fun load_jclass
(name
)
48 var class_loader
= self.class_loader
49 if class_loader
== null then
50 find_class_loader app
.native_context
51 class_loader
= self.class_loader
52 assert class_loader
!= null
55 var class_loader_method
= self.class_loader_method
56 assert class_loader_method
!= null
58 return load_jclass_intern
(class_loader
, class_loader_method
, name
)
61 private fun find_class_loader
(native_context
: NativeContext) import jni_env
, class_loader
=, JavaObject.as nullable, class_loader_method
=, JMethodID.as nullable `{
62 JNIEnv *env = Sys_jni_env(self);
64 // Retrieve main activity
65 jclass class_context = (*env)->GetObjectClass(env, native_context);
66 if (class_context == NULL) {
67 __android_log_print(ANDROID_LOG_ERROR, "Nit", "Failed to retrieve activity class");
68 (*env)->ExceptionDescribe(env);
72 jmethodID class_activity_getClassLoader = (*env)->GetMethodID(env, class_context, "getClassLoader", "()Ljava/lang/ClassLoader;");
73 if (class_activity_getClassLoader == NULL) {
74 __android_log_print(ANDROID_LOG_ERROR, "Nit", "Failed to retrieve 'getClassLoader' method");
75 (*env)->ExceptionDescribe(env);
79 // Call activity.getClassLoader
80 jobject instance_class_loader = (*env)->CallObjectMethod(env, native_context, class_activity_getClassLoader);
81 if (instance_class_loader == NULL) {
82 __android_log_print(ANDROID_LOG_ERROR, "Nit", "Failed to retrieve class loader instance");
83 (*env)->ExceptionDescribe(env);
87 jclass class_class_loader = (*env)->GetObjectClass(env, instance_class_loader);
88 if (class_class_loader == NULL) {
89 __android_log_print(ANDROID_LOG_ERROR, "Nit", "Failed to retrieve class of class loader");
90 (*env)->ExceptionDescribe(env);
94 // Get the method ClassLoader.findClass
95 jmethodID class_class_loader_findClass = (*env)->GetMethodID(env, class_class_loader, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;");
96 if (class_class_loader_findClass == NULL) {
97 __android_log_print(ANDROID_LOG_ERROR, "Nit", "Failed to retrieve 'findClass' method");
98 (*env)->ExceptionDescribe(env);
102 // Return the values to Nit
103 Sys_class_loader__assign(self, JavaObject_as_nullable((*env)->NewGlobalRef(env, instance_class_loader)));
104 Sys_class_loader_method__assign(self, JMethodID_as_nullable(class_class_loader_findClass));
107 (*env)->DeleteLocalRef(env, class_context);
108 (*env)->DeleteLocalRef(env, instance_class_loader);
109 (*env)->DeleteLocalRef(env, class_class_loader);
112 private fun load_jclass_intern
(instance_class_loader
: JavaObject, class_loader_findClass
: JMethodID, name
: CString): JClass import jni_env
`{
113 JNIEnv *env = Sys_jni_env(self);
114 jobject class_name = (*env)->NewStringUTF(env, name);
116 jclass java_class = (*env)->CallObjectMethod(env, instance_class_loader, class_loader_findClass, class_name);
117 if (java_class == NULL) {
118 __android_log_print(ANDROID_LOG_ERROR, "Nit", "Failed loading targeted class");
119 (*env)->ExceptionDescribe(env);
123 (*env)->DeleteLocalRef(env, class_name);