From: Alexis Laferrière Date: Sun, 3 Aug 2014 00:09:47 +0000 (-0400) Subject: lib/android: intro our very own NitActivity X-Git-Tag: v0.7.3~21^2~8 X-Git-Url: http://nitlanguage.org lib/android: intro our very own NitActivity Signed-off-by: Alexis Laferrière --- diff --git a/lib/android/NitActivity.java b/lib/android/NitActivity.java new file mode 100644 index 0000000..3744988 --- /dev/null +++ b/lib/android/NitActivity.java @@ -0,0 +1,111 @@ +/* This file is part of NIT ( http://www.nitlanguage.org ). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package nit.app; + +import android.app.Activity; +import android.os.Bundle; + +/* + * Entry point to Nit applications on Android, redirect most calls to Nit + */ +public class NitActivity extends Activity { + + // Nit activity associated to `this` + protected int nitActivity = 0; + + /* + * Calls to Nit or to the C framework + */ + + static { + System.loadLibrary("main"); + } + + /* + * Callbacks to Nit through C + */ + protected native int nitRegisterActivity(); + protected native void nitOnCreate(int activity, Bundle savedInstanceState); + protected native void nitOnStart(int activity); + protected native void nitOnRestart(int activity); + protected native void nitOnResume(int activity); + protected native void nitOnPause(int activity); + protected native void nitOnStop(int activity); + protected native void nitOnDestroy(int activity); + protected native void nitOnSaveInstanceState(int activity, Bundle savedInstanceState); + protected native void nitOnRestoreInstanceState(int activity, Bundle savedInstanceState); + + /* + * Implementation of OS callbacks + */ + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + nitActivity = nitRegisterActivity(); + + nitOnCreate(nitActivity, savedInstanceState); + } + + @Override + protected void onStart() { + super.onStart(); + nitOnStart(nitActivity); + } + + @Override + protected void onRestart() { + super.onRestart(); + nitOnRestart(nitActivity); + } + + @Override + protected void onResume() { + super.onResume(); + nitOnResume(nitActivity); + } + + @Override + protected void onPause() { + super.onPause(); + nitOnPause(nitActivity); + } + + @Override + protected void onStop() { + super.onStop(); + nitOnStop(nitActivity); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + nitOnDestroy(nitActivity); + } + + @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + super.onSaveInstanceState(savedInstanceState); + nitOnSaveInstanceState(nitActivity, savedInstanceState); + } + + @Override + public void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + nitOnRestoreInstanceState(nitActivity, savedInstanceState); + } +} diff --git a/lib/android/nit_activity.nit b/lib/android/nit_activity.nit new file mode 100644 index 0000000..765ed01 --- /dev/null +++ b/lib/android/nit_activity.nit @@ -0,0 +1,251 @@ +# This file is part of NIT (http://www.nitlanguage.org). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Some documentation of this module has been adapted from the +# Android Open Source Project. + +# Core implementation of `app.nit` on Android using a custom Java entry point +# +# This module is implemented in 3 languages: +# +# * The Java code, in `NitActivity.java` acts as the entry point registered +# to the Android OS. It relays most of the Android callbacks to C. +# In theory, there may be more than one instance of `NitActivity` alive at +# a given time. They hold a reference to the corresponding Nit `Activity` +# in the attribute `nitActivity`. +# +# * The C code is defined in the top part of this source file. It acts as a +# glue between Java and Nit by relaying calls between both languages. +# It keeps a global variables reference to the Java VM and the Nit `App`. +# +# * The Nit code defines the `Activity` class with the callbacks from Android. +# The callback methods should be redefined by user modules. +# +# The main is invoked when the native library is dynamically linked by +# the Java virtual machine. For this reason, the main _must_ execute quickly, +# on the main UI thread at least. +module nit_activity is + extra_java_files "NitActivity.java" + android_activity "nit.app.NitActivity" +end + +import platform +import log +import activities +import bundle +import dalvik + +in "C body" `{ + + #include + #include + + // Nit's App running instance + App global_app; + + // Java VM that launched this program + JavaVM *global_jvm; + + // JNI callback on loading this program + jint JNI_OnLoad(JavaVM *vm, void *reserved) { + // Set aside the Java VM + global_jvm = vm; + + // Invoke Nit system and main + main(0, NULL); + + return JNI_VERSION_1_2; + } + + /* + * Implementations of NitActivity.java native methods + */ + + JNIEXPORT jint JNICALL Java_nit_app_NitActivity_nitRegisterActivity + (JNIEnv *env, jobject java_activity) + { + Activity nit_activity = App_register_activity(global_app, java_activity); + Activity_incr_ref(nit_activity); + return (jint)(void*)nit_activity; + } + + JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnCreate + (JNIEnv *env, jobject java_activity, jint nit_activity, jobject saved_state) + { + Activity_on_create((Activity)nit_activity, saved_state); + } + + JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnStart + (JNIEnv *env, jobject java_activity, jint nit_activity) + { + Activity_on_start((Activity)nit_activity); + } + + JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnRestart + (JNIEnv *env, jobject java_activity, jint nit_activity) + { + Activity_on_restart((Activity)nit_activity); + } + + JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnResume + (JNIEnv *env, jobject java_activity, jint nit_activity) + { + Activity_on_resume((Activity)nit_activity); + } + + JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnPause + (JNIEnv *env, jobject java_activity, jint nit_activity) + { + Activity_on_pause((Activity)nit_activity); + } + + JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnStop + (JNIEnv *env, jobject java_activity, jint nit_activity) + { + Activity_on_stop((Activity)nit_activity); + } + + JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnDestroy + (JNIEnv *env, jobject java_activity, jint nit_activity) + { + Activity_on_destroy((Activity)nit_activity); + } + + JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnSaveInstanceState + (JNIEnv *env, jobject java_activity, jint nit_activity, jobject saved_state) + { + Activity_on_save_instance_state((Activity)nit_activity, saved_state); + } + + JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnRestoreInstanceState + (JNIEnv *env, jobject java_activity, jint nit_activity, jobject saved_state) + { + Activity_on_restore_instance_state((Activity)nit_activity, saved_state); + } +`} + +# Wrapper to our Java `NitActivity` +extern class NativeNitActivity in "Java" `{ nit.app.NitActivity `} + super NativeActivity +end + +redef class Sys + redef fun jvm `{ return global_jvm; `} +end + +redef class App + # Known activities + var activities = new Array[Activity] + + # The main Java Activity of this application + redef fun native_activity do return activities.first.native + + redef fun setup do set_global_app + + # Register app in C + private fun set_global_app import register_activity, + Activity.on_create, Activity.on_destroy, + Activity.on_start, Activity.on_restart, Activity.on_stop, + Activity.on_pause, Activity.on_resume, + Activity.on_save_instance_state, Activity.on_restore_instance_state `{ + App_incr_ref(recv); + global_app = recv; + `} + + # Create the Nit side to this new `native` Java activity, and return it to Java + private fun register_activity(native: NativeNitActivity): Activity + do + native = native.new_global_ref + var activity = new Activity(native) + activities.add activity + return activity + end +end + +# An Android activity +# +# You must implement the callbacks (prefixed with `on_`) to follow the +# standard Android life-cycle. +class Activity + # Native Java activity + var native: NativeActivity + + # Notification from Android, the activity is created + # + # Do your normal static set up here. + # + # If available, `save_state` contains the activity's previous state + # as registered by `on_save_instance_state`. + # + # Followed by `on_start`. + fun on_create(save_state: NativeBundle) do end + + # Notification from Android, the activity has been restarted + # + # Followed by `on_start`. + fun on_restart do end + + # Notification from Android, the activity has been started + # + # Followed by `on_resume` or `on_stop`. + fun on_start do end + + # Notification from Android, the activity has been resumed + # + # Followed by `on_pause` + fun on_resume do end + + # Notification from Android, the activity has been paused + # + # Followed by `on_resume` or `on_stop`. + fun on_pause do end + + # Notification from Android, the activity has been stopped + # + # Followed by `on_restart` or `on_destroy`. + fun on_stop do end + + # Notification from Android, the activity is being destroyed + # + # Clean up and exit. + fun on_destroy + do + native.delete_global_ref + app.activities.remove self + end + + # Notification from Android, the activity is being re-initialized from a `save_state` + # + # Occurs after `on_start`. + fun on_restore_instance_state(save_state: NativeBundle) do end + + # Notification from Android, the activity may be stopped, save state + # + # Occurs before `on_stop` and, without guarantee, before or after `on_pause`. + fun on_save_instance_state(save_state: NativeBundle) do end + + # Notification from Android, the system is running low on memory + # + # Try to reduce your memory use. + fun on_low_memory do end + + # Notification from Android, the current window of the activity has lost or gained focus + fun on_window_focus_changed(has_focus: Bool) do end + + # Notification from Android, the current device configuration has changed + fun on_configuration_changed do end +end + +# Set up global data in C and leave it to Android to callback Java, which we relay to Nit +app.setup