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.

Introduced classes

class Activity

android :: Activity

An Android activity
extern class NativeNitActivity

android :: NativeNitActivity

Wrapper to our Java NitActivity

Redefined classes

redef class App

android :: nit_activity $ App

App subclasses are cross-platform applications
redef abstract class AppComponent

android :: nit_activity $ AppComponent

An element of an application that is notified of the application life cycle
redef class Sys

android :: nit_activity $ Sys

The main class of the program.

All class definitions

class Activity

android $ Activity

An Android activity
redef class App

android :: nit_activity $ App

App subclasses are cross-platform applications
redef abstract class AppComponent

android :: nit_activity $ AppComponent

An element of an application that is notified of the application life cycle
extern class NativeNitActivity

android $ NativeNitActivity

Wrapper to our Java NitActivity
redef class Sys

android :: nit_activity $ Sys

The main class of the program.
package_diagram android::nit_activity nit_activity android::log log android::nit_activity->android::log android::key_event key_event android::nit_activity->android::key_event android\>bundle\> bundle android::nit_activity->android\>bundle\> android::dalvik dalvik android::nit_activity->android::dalvik android::platform platform android::log->android::platform android::key_event->android::platform json json android\>bundle\>->json android android android\>bundle\>->android android::activities activities android::dalvik->android::activities ...android::platform ... ...android::platform->android::platform ...json ... ...json->json ...android ... ...android->android ...android::activities ... ...android::activities->android::activities android::native_ui native_ui android::native_ui->android::nit_activity android::wifi wifi android::wifi->android::nit_activity android::service service android::service->android::nit_activity android::ui ui android::ui->android::native_ui android::ui... ... android::ui...->android::ui a_star-m a_star-m a_star-m->android::wifi a_star-m... ... a_star-m...->a_star-m android::at_boot at_boot android::at_boot->android::service android::at_boot... ... android::at_boot...->android::at_boot

Ancestors

module abstract_collection

core :: abstract_collection

Abstract collection classes and services.
module abstract_text

core :: abstract_text

Abstract class for manipulation of sequences of characters
module activities

android :: activities

Android Activities wrapper
module app

app :: app

app.nit is a framework to create cross-platform applications
module app_base

app :: app_base

Base of the app.nit framework, defines App
module array

core :: array

This module introduces the standard array structure.
module assets

app :: assets

Portable services to load resources from the assets folder
module aware

android :: aware

Android compatibility module
module bitset

core :: bitset

Services to handle BitSet
module bytes

core :: bytes

Services for byte streams and arrays
module caching

serialization :: caching

Services for caching serialization engines
module circular_array

core :: circular_array

Efficient data structure to access both end of the sequence.
module codec_base

core :: codec_base

Base for codecs to use with streams
module codecs

core :: codecs

Group module for all codec-related manipulations
module collection

core :: collection

This module define several collection classes.
module collections

java :: collections

Basic Java collections
module core

core :: core

Standard classes and methods used by default by Nit programs and libraries.
module engine_tools

serialization :: engine_tools

Advanced services for serialization engines
module environ

core :: environ

Access to the environment variables of the process
module error

json :: error

Intro JsonParseError which is exposed by all JSON reading APIs
module error

core :: error

Standard error-management infrastructure.
module exec

core :: exec

Invocation and management of operating system sub-processes.
module ffi_support

java :: ffi_support

Core supporting services for the FFI with Java
module file

core :: file

File manipulations (create, read, write, etc.)
module fixed_ints

core :: fixed_ints

Basic integers of fixed-precision
module fixed_ints_text

core :: fixed_ints_text

Text services to complement fixed_ints
module flat

core :: flat

All the array-based text representations
module gc

core :: gc

Access to the Nit internal garbage collection mechanism
module hash_collection

core :: hash_collection

Introduce HashMap and HashSet.
module inspect

serialization :: inspect

Refine Serializable::inspect to show more useful information
module iso8859_1

core :: iso8859_1

Codec for ISO8859-1 I/O
module java

java :: java

Supporting services for the FFI with Java and to access Java libraries
module json

json :: json

Read and write JSON formatted text using the standard serialization services
module jvm

jvm :: jvm

Java Virtual Machine invocation API and others services from the JNI C API
module kernel

core :: kernel

Most basic classes and methods.
module list

core :: list

This module handle double linked lists
module math

core :: math

Mathematical operations
module meta

meta :: meta

Simple user-defined meta-level to manipulate types of instances as object.
module native

core :: native

Native structures for text and bytes
module numeric

core :: numeric

Advanced services for Numeric types
module parser_base

parser_base :: parser_base

Simple base for hand-made parsers of all kinds
module platform

android :: platform

Triggers compilation for the android platform
module poset

poset :: poset

Pre order sets and partial order set (ie hierarchies)
module protocol

core :: protocol

module queue

core :: queue

Queuing data structures and wrappers
module range

core :: range

Module for range of discrete objects.
module re

core :: re

Regular expression support for all services based on Pattern
module ropes

core :: ropes

Tree-based representation of a String.
module safe

serialization :: safe

Services for safer deserialization engines
module serialization

serialization :: serialization

General serialization services
module serialization_core

serialization :: serialization_core

Abstract services to serialize Nit objects to different formats
module serialization_read

json :: serialization_read

Services to read JSON: deserialize_json and JsonDeserializer
module serialization_write

json :: serialization_write

Services to write Nit objects to JSON strings: serialize_to_json and JsonSerializer
module sorter

core :: sorter

This module contains classes used to compare things and sorts arrays.
module static

json :: static

Static interface to read Nit objects from JSON strings
module stream

core :: stream

Input and output streams of characters
module text

core :: text

All the classes and methods related to the manipulation of text entities
module time

core :: time

Management of time and dates
module union_find

core :: union_find

union–find algorithm using an efficient disjoint-set data structure
module utf8

core :: utf8

Codec for UTF-8 I/O

Parents

module bundle

android :: bundle

A mapping class of String to various value types used by the
module dalvik

android :: dalvik

Java related services specific to Android and its Dalvik VM
module log

android :: log

Advanced Android logging services

Children

module native_ui

android :: native_ui

Native services from the android.view and android.widget namespaces
module service

android :: service

Android service support for app.nit centered around the class Service
module wifi

android :: wifi

Simple wrapper of the Android WiFi services

Descendants

module a_star-m

a_star-m

module at_boot

android :: at_boot

Import this module to launch Service at device boot
module http_request

android :: http_request

Android implementation of app:http_request
module ui

android :: ui

Views and services to use the Android native user interface
module ui_test

android :: ui_test

Test for app.nit's UI services
# 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 "nit.app.NitActivity"
	android_activity "nit.app.NitActivity"
end

import platform
import log
import activities
import key_event
import bundle
import dalvik

in "C body" `{

	#include <jni.h>
	#include <android/log.h>

	// 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
		int main(int argc, char ** argv);
		main(0, NULL);

		return JNI_VERSION_1_2;
	}

	/*
	 * Implementations of NitActivity.java native methods
	 */

	JNIEXPORT jlong 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 (jlong)(void*)nit_activity;
	}

	JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnCreate
	  (JNIEnv *env, jobject java_activity, jlong 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, jlong nit_activity)
	{
		Activity_on_start((Activity)nit_activity);
	}

	JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnRestart
	  (JNIEnv *env, jobject java_activity, jlong nit_activity)
	{
		Activity_on_restart((Activity)nit_activity);
	}

	JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnResume
	  (JNIEnv *env, jobject java_activity, jlong nit_activity)
	{
		Activity_on_resume((Activity)nit_activity);
	}

	JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnPause
	  (JNIEnv *env, jobject java_activity, jlong nit_activity)
	{
		Activity_on_pause((Activity)nit_activity);
	}

	JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnStop
	  (JNIEnv *env, jobject java_activity, jlong nit_activity)
	{
		Activity_on_stop((Activity)nit_activity);
	}

	JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnDestroy
	  (JNIEnv *env, jobject java_activity, jlong nit_activity)
	{
		Activity_on_destroy((Activity)nit_activity);
	}

	JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnSaveInstanceState
	  (JNIEnv *env, jobject java_activity, jlong 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, jlong nit_activity, jobject saved_state)
	{
		Activity_on_restore_instance_state((Activity)nit_activity, saved_state);
	}

	JNIEXPORT jboolean JNICALL Java_nit_app_NitActivity_nitOnBackPressed
	  (JNIEnv *env, jobject java_activity, jlong nit_activity)
	{
		return (jboolean)Activity_on_back_pressed((Activity)nit_activity);
	}

	JNIEXPORT jboolean JNICALL Java_nit_app_NitActivity_nitOnKeyDown
	  (JNIEnv *env, jobject java_activity, jlong nit_activity, jint keyCode, jobject event)
	{
		return (jboolean)Activity_on_key_down((Activity)nit_activity, keyCode, event);
	}

	JNIEXPORT jboolean JNICALL Java_nit_app_NitActivity_nitOnKeyLongPress
	  (JNIEnv *env, jobject java_activity, jlong nit_activity, jint keyCode, jobject event)
	{
		return (jboolean)Activity_on_key_long_press((Activity)nit_activity, keyCode, event);
	}

	JNIEXPORT jboolean JNICALL Java_nit_app_NitActivity_nitOnKeyMultiple
	  (JNIEnv *env, jobject java_activity, jlong nit_activity, jint keyCode, jint count, jobject event)
	{
		return (jboolean)Activity_on_key_multiple((Activity)nit_activity, keyCode, count, event);
	}

	JNIEXPORT jboolean JNICALL Java_nit_app_NitActivity_nitOnKeyUp
	  (JNIEnv *env, jobject java_activity, jlong nit_activity, jint keyCode, jobject event)
	{
		return (jboolean)Activity_on_key_up((Activity)nit_activity, keyCode, event);
	}
`}

# 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,
	Activity.on_back_pressed,
	Activity.on_key_down, Activity.on_key_long_press,
	Activity.on_key_multiple, Activity.on_key_up `{
		App_incr_ref(self);
		global_app = self;
	`}

	# 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

redef class AppComponent
	# The application is starting or restarting, it is visible to the user
	fun on_start do end

	# The application is being destroyed
	fun on_destroy do 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
		app.on_create
		app.on_restore_state
	end

	# Notification from Android, the activity has been restarted
	#
	# Followed by `on_start`.
	fun on_restart do app.on_restart

	# Notification from Android, the activity has been started
	#
	# Followed by `on_resume` or `on_stop`.
	fun on_start do app.on_start

	# Notification from Android, the activity has been resumed
	#
	# Followed by `on_pause`
	fun on_resume do app.on_resume

	# Notification from Android, the activity has been paused
	#
	# Followed by `on_resume` or `on_stop`.
	fun on_pause do app.on_pause

	# Notification from Android, the activity has been stopped
	#
	# Followed by `on_restart` or `on_destroy`.
	fun on_stop do app.on_stop

	# Notification from Android, the activity is being destroyed
	#
	# Clean up and exit.
	fun on_destroy
	do
		app.on_destroy

		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 app.on_save_state

	# Notification from Android, the system is running low on memory
	#
	# Try to reduce your memory use.
	fun on_low_memory do force_garbage_collection

	# 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

	# The back key has been pressed
	#
	# Return `true` if the event has been handled.
	fun on_back_pressed: Bool do return false

	# A key has been pressed
	#
	# Return `true` if the event has been handled.
	fun on_key_down(key_code: Int, event: NativeKeyEvent): Bool do return false

	# A key has been long pressed
	#
	# Return `true` if the event has been handled.
	fun on_key_long_press(key_code: Int, event: NativeKeyEvent): Bool do return false

	# Multiple down/up pairs of the same key have occurred in a row
	#
	# Return `true` if the event has been handled.
	fun on_key_multiple(key_code, count: Int, event: NativeKeyEvent): Bool do return false

	# A key has been released
	#
	# Return `true` if the event has been handled.
	fun on_key_up(key_code: Int, event: NativeKeyEvent): Bool do return false
end

# Set up global data in C and leave it to Android to callback Java, which we relay to Nit
app.setup
lib/android/nit_activity.nit:18,1--325,9