application module events added

This commit is contained in:
Vladimir Enchev
2015-06-01 15:10:47 +03:00
parent 79caa9185c
commit c6549343bc
6 changed files with 231 additions and 109 deletions

View File

@ -3,6 +3,10 @@ import definition = require("application");
import fs = require("file-system"); import fs = require("file-system");
import fileSystemAccess = require("file-system/file-system-access"); import fileSystemAccess = require("file-system/file-system-access");
import styleScope = require("ui/styling/style-scope"); import styleScope = require("ui/styling/style-scope");
import observable = require("data/observable");
var events = new observable.Observable();
require("utils/module-merge").merge(events, exports);
export var cssFile: string = "app.css" export var cssFile: string = "app.css"

View File

@ -43,6 +43,9 @@ var initEvents = function () {
if (exports.onExit) { if (exports.onExit) {
exports.onExit(); exports.onExit();
} }
exports.notify({ eventName: "onExit", object: androidApp, android: activity, ios: undefined });
androidApp.startActivity = undefined; androidApp.startActivity = undefined;
} }
@ -58,6 +61,9 @@ var initEvents = function () {
if (exports.onSuspend) { if (exports.onSuspend) {
exports.onSuspend(); exports.onSuspend();
} }
exports.notify({ eventName: "onSuspend", object: androidApp, android: activity, ios: undefined });
} }
if (androidApp.onActivityPaused) { if (androidApp.onActivityPaused) {
@ -69,6 +75,9 @@ var initEvents = function () {
if (exports.onResume) { if (exports.onResume) {
exports.onResume(); exports.onResume();
} }
exports.notify({ eventName: "onResume", object: androidApp, android: activity, ios: undefined });
} }
if (androidApp.onActivityResumed) { if (androidApp.onActivityResumed) {
@ -183,6 +192,8 @@ class AndroidApplication implements dts.AndroidApplication {
exports.onLaunch(intent); exports.onLaunch(intent);
} }
exports.notify({ eventName: "onLaunch", object: this, android: intent, ios: undefined });
/* In the onLaunch event we expect the following setup, which ensures a root frame: /* In the onLaunch event we expect the following setup, which ensures a root frame:
* var frame = require("ui/frame"); * var frame = require("ui/frame");
* var rootFrame = new frame.Frame(); * var rootFrame = new frame.Frame();
@ -224,6 +235,8 @@ global.__onUncaughtError = function (error: Error) {
} }
exports.onUncaughtError(nsError); exports.onUncaughtError(nsError);
exports.notify({ eventName: "onUncaughtError", object: appModule.android, android: error, ios: undefined });
} }
exports.start = function () { exports.start = function () {

View File

@ -3,6 +3,7 @@
*/ */
declare module "application" { declare module "application" {
import cssSelector = require("ui/styling/css-selector"); import cssSelector = require("ui/styling/css-selector");
import observable = require("data/observable");
/** /**
* An extended JavaScript Error which will have the nativeError property initialized in case the error is caused by executing platform-specific code. * An extended JavaScript Error which will have the nativeError property initialized in case the error is caused by executing platform-specific code.
@ -14,19 +15,34 @@ declare module "application" {
nativeError: any; nativeError: any;
} }
/** /**
* The main page path (without the file extension) for the application starting from the application root. * Event data containing information for the application events.
* For example if you have page called "main.js" in a folder called "subFolder" and your root folder is "app" you can specify mainModule like this: */
* var application = require("application"); export interface ApplicationEventData extends observable.EventData {
* application.mainModule = "app/subFolder/main"; /**
* application.start(); * Gets the native iOS event arguments. Valid only when running on iOS.
*/ */
ios: any;
/**
* Gets the native Android event arguments. Valid only when running on Android.
*/
android: any;
}
/**
* The main page path (without the file extension) for the application starting from the application root.
* For example if you have page called "main.js" in a folder called "subFolder" and your root folder is "app" you can specify mainModule like this:
* var application = require("application");
* application.mainModule = "app/subFolder/main";
* application.start();
*/
export var mainModule: string; export var mainModule: string;
/** /**
* An application level static resources. * An application level static resources.
*/ */
export var resources: any; export var resources: any;
/** /**
* The application level css file name (starting from the application root). Used to set css across all pages. * The application level css file name (starting from the application root). Used to set css across all pages.
@ -44,14 +60,14 @@ declare module "application" {
*/ */
export function loadCss(): void; export function loadCss(): void;
/** /**
* Call this method to start the application. Important: All code after this method call will not be executed! * Call this method to start the application. Important: All code after this method call will not be executed!
*/ */
export function start(); export function start();
/** /**
* The main entry point event. This method is expected to use the root frame to navigate to the main application page. * The main entry point event. This method is expected to use the root frame to navigate to the main application page.
*/ */
export function onLaunch(context: any): void; export function onLaunch(context: any): void;
/** /**
@ -62,136 +78,186 @@ declare module "application" {
*/ */
export function onUncaughtError(error: NativeScriptError): void; export function onUncaughtError(error: NativeScriptError): void;
/** /**
* This method will be called when the Application is suspended. * This method will be called when the Application is suspended.
*/ */
export function onSuspend(); export function onSuspend();
/** /**
* This method will be called when the Application is resumed after it has been suspended. * This method will be called when the Application is resumed after it has been suspended.
*/ */
export function onResume(); export function onResume();
/** /**
* This method will be called when the Application is about to exit. * This method will be called when the Application is about to exit.
*/ */
export function onExit(); export function onExit();
/** /**
* This method will be called when there is low memory on the target device. * This method will be called when there is low memory on the target device.
*/ */
export function onLowMemory(); export function onLowMemory();
/** /**
* This is the Android-specific application object instance. * A basic method signature to hook an event listener (shortcut alias to the addEventListener method).
* Encapsulates methods and properties specific to the Android platform. * @param eventNames - String corresponding to events (e.g. "onLaunch"). Optionally could be used more events separated by `,` (e.g. "onLaunch", "onSuspend").
* Will be undefined when TargetOS is iOS. * @param callback - Callback function which will be executed when event is raised.
*/ * @param thisArg - An optional parameter which will be used as `this` context for callback execution.
*/
export function on(eventNames: string, callback: (data: any) => void, thisArg?: any);
/**
* Notifies all the registered listeners for the event provided in the data.eventName.
* @param data The data associated with the event.
*/
export function notify(data: ApplicationEventData): void;
/**
* Checks whether a listener is registered for the specified event name.
* @param eventName The name of the event to check for.
*/
export function hasListeners(eventName: string): boolean;
/**
* This event is raised on application launch.
*/
export function on(event: "onLaunch", callback: (args: any) => void, thisArg?: any);
/**
* This event is raised when an uncaught error occurs while the application is running.
*/
export function on(event: "onUncaughtError", callback: (args: any) => void, thisArg?: any);
/**
* This event is raised when the Application is suspended.
*/
export function on(event: "onSuspend", callback: (args: any) => void, thisArg?: any);
/**
* This event is raised when the Application is resumed after it has been suspended.
*/
export function on(event: "onResume", callback: (args: any) => void, thisArg?: any);
/**
* This event is raised when the Application is about to exit.
*/
export function on(event: "onExit", callback: (args: any) => void, thisArg?: any);
/**
* This event is raised when there is low memory on the target device.
*/
export function on(event: "onLowMemory", callback: (args: any) => void, thisArg?: any);
/**
* This is the Android-specific application object instance.
* Encapsulates methods and properties specific to the Android platform.
* Will be undefined when TargetOS is iOS.
*/
export var android: AndroidApplication; export var android: AndroidApplication;
/** /**
* This is the iOS-specific application object instance. * This is the iOS-specific application object instance.
* Encapsulates methods and properties specific to the iOS platform. * Encapsulates methods and properties specific to the iOS platform.
* Will be undefined when TargetOS is Android. * Will be undefined when TargetOS is Android.
*/ */
export var ios: iOSApplication; export var ios: iOSApplication;
/** /**
* The abstraction of an Android-specific application object. * The abstraction of an Android-specific application object.
*/ */
export interface AndroidApplication { export interface AndroidApplication {
/** /**
* The [android Application](http://developer.android.com/reference/android/app/Application.html) object instance provided to the init of the module. * The [android Application](http://developer.android.com/reference/android/app/Application.html) object instance provided to the init of the module.
*/ */
nativeApp: android.app.Application; nativeApp: android.app.Application;
/** /**
* The application's [android Context](http://developer.android.com/reference/android/content/Context.html) object instance. * The application's [android Context](http://developer.android.com/reference/android/content/Context.html) object instance.
*/ */
context: android.content.Context; context: android.content.Context;
/** /**
* The currently active (loaded) [android Activity](http://developer.android.com/reference/android/app/Activity.html). This property is automatically updated upon Activity events. * The currently active (loaded) [android Activity](http://developer.android.com/reference/android/app/Activity.html). This property is automatically updated upon Activity events.
*/ */
foregroundActivity: android.app.Activity; foregroundActivity: android.app.Activity;
/** /**
* The currently active (loaded) Context. This is typically the top-level Activity that is just created. * The currently active (loaded) Context. This is typically the top-level Activity that is just created.
*/ */
currentContext: android.content.Context; currentContext: android.content.Context;
/** /**
* The main (start) Activity for the application. * The main (start) Activity for the application.
*/ */
startActivity: android.app.Activity; startActivity: android.app.Activity;
/** /**
* The name of the application package. * The name of the application package.
*/ */
packageName: string; packageName: string;
/** /**
* This method is called by the JavaScript Bridge when navigation to a new activity is triggered. * This method is called by the JavaScript Bridge when navigation to a new activity is triggered.
* @param intent - Native (android) intent used to create the activity. * @param intent - Native (android) intent used to create the activity.
* Returns com.tns.NativeScriptActivity.extend implementation. * Returns com.tns.NativeScriptActivity.extend implementation.
*/ */
getActivity(intent: android.content.Intent): any; getActivity(intent: android.content.Intent): any;
/** /**
* Direct handler of the [onActivityCreated method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html). * Direct handler of the [onActivityCreated method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
*/ */
onActivityCreated: (activity: android.app.Activity, bundle: android.os.Bundle) => void; onActivityCreated: (activity: android.app.Activity, bundle: android.os.Bundle) => void;
/** /**
* Direct handler of the [onActivityDestroyed method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html). * Direct handler of the [onActivityDestroyed method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
*/ */
onActivityDestroyed: (activity: android.app.Activity) => void; onActivityDestroyed: (activity: android.app.Activity) => void;
/** /**
* Direct handler of the [onActivityDestroyed method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html). * Direct handler of the [onActivityDestroyed method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
*/ */
onActivityStarted: (activity: android.app.Activity) => void; onActivityStarted: (activity: android.app.Activity) => void;
/** /**
* Direct handler of the [onActivityPaused method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html). * Direct handler of the [onActivityPaused method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
*/ */
onActivityPaused: (activity: android.app.Activity) => void; onActivityPaused: (activity: android.app.Activity) => void;
/** /**
* Direct handler of the [onActivityResumed method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html). * Direct handler of the [onActivityResumed method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
*/ */
onActivityResumed: (activity: android.app.Activity) => void; onActivityResumed: (activity: android.app.Activity) => void;
/** /**
* Direct handler of the [onActivityStopped method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html). * Direct handler of the [onActivityStopped method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
*/ */
onActivityStopped: (activity: android.app.Activity) => void; onActivityStopped: (activity: android.app.Activity) => void;
/** /**
* Direct handler of the [onActivitySaveInstanceState method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html). * Direct handler of the [onActivitySaveInstanceState method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
*/ */
onSaveActivityState: (activity: android.app.Activity, bundle: android.os.Bundle) => void; onSaveActivityState: (activity: android.app.Activity, bundle: android.os.Bundle) => void;
/** /**
* Direct handler of the onActivityResult method. * Direct handler of the onActivityResult method.
*/ */
onActivityResult: (requestCode: number, resultCode: number, data: android.content.Intent) => void onActivityResult: (requestCode: number, resultCode: number, data: android.content.Intent) => void
} }
/* tslint:disable */ /* tslint:disable */
/** /**
* The abstraction of an iOS-specific application object. * The abstraction of an iOS-specific application object.
*/ */
export interface iOSApplication { export interface iOSApplication {
/* tslint:enable */ /* tslint:enable */
/** /**
* The root view controller for the application. * The root view controller for the application.
*/ */
rootController: UIViewController; rootController: UIViewController;
/** /**
* The [UIApplication](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/index.html) object instance provided to the init of the module. * The [UIApplication](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/index.html) object instance provided to the init of the module.
*/ */
nativeApp: UIApplication; nativeApp: UIApplication;
} }
} }

View File

@ -14,7 +14,7 @@ export var mainModule: string;
class Window extends UIWindow { class Window extends UIWindow {
private _content: view.View; private _content: view.View;
initWithFrame(frame: CGRect): UIWindow { initWithFrame(frame: CGRect): UIWindow {
var window = super.initWithFrame(frame); var window = super.initWithFrame(frame);
if (window) { if (window) {
@ -50,6 +50,8 @@ class TNSAppDelegate extends UIResponder implements UIApplicationDelegate {
exports.onLaunch(); exports.onLaunch();
} }
exports.notify({ eventName: "onLaunch", object: this, android: undefined, ios: launchOptions });
var topFrame = frame.topmost(); var topFrame = frame.topmost();
if (!topFrame) { if (!topFrame) {
if (mainModule) { if (mainModule) {
@ -74,6 +76,8 @@ class TNSAppDelegate extends UIResponder implements UIApplicationDelegate {
if (exports.onResume) { if (exports.onResume) {
exports.onResume(); exports.onResume();
} }
exports.notify({ eventName: "onResume", object: this, android: undefined, ios: application });
} }
applicationWillResignActive(application: UIApplication) { applicationWillResignActive(application: UIApplication) {
@ -84,6 +88,8 @@ class TNSAppDelegate extends UIResponder implements UIApplicationDelegate {
if (exports.onSuspend) { if (exports.onSuspend) {
exports.onSuspend(); exports.onSuspend();
} }
exports.notify({ eventName: "onSuspend", object: this, android: undefined, ios: application });
} }
applicationWillEnterForeground(application: UIApplication) { applicationWillEnterForeground(application: UIApplication) {
@ -94,12 +100,16 @@ class TNSAppDelegate extends UIResponder implements UIApplicationDelegate {
if (exports.onExit) { if (exports.onExit) {
exports.onExit(); exports.onExit();
} }
exports.notify({ eventName: "onExit", object: this, android: undefined, ios: application });
} }
applicationDidReceiveMemoryWarning(application: UIApplication) { applicationDidReceiveMemoryWarning(application: UIApplication) {
if (exports.onLowMemory) { if (exports.onLowMemory) {
exports.onLowMemory(); exports.onLowMemory();
} }
exports.notify({ eventName: "onLowMemory", object: this, android: undefined, ios: application });
} }
applicationOpenURLSourceApplicationAnnotation(application: UIApplication, url: NSURL, sourceApplication: string, annotation: any): boolean { applicationOpenURLSourceApplicationAnnotation(application: UIApplication, url: NSURL, sourceApplication: string, annotation: any): boolean {
@ -147,5 +157,7 @@ exports.start = function () {
} }
exports.onUncaughtError(error); exports.onUncaughtError(error);
definition.notify({ eventName: "onUncaughtError", object: <any>definition.ios, android: undefined, ios: error });
} }
} }

View File

@ -1,3 +1,28 @@
import application = require("application"); import application = require("application");
application.mainModule = "app/mainPage"; application.mainModule = "app/mainPage";
application.on("onLaunch", function (args) {
console.log("onLaunch: " + args);
});
application.on("onUncaughtError", function (args) {
console.log("onUncaughtError: " + args);
});
application.on("onSuspend", function (args) {
console.log("onSuspend: " + args);
});
application.on("onResume", function (args) {
console.log("onResume: " + args);
});
application.on("onExit", function (args) {
console.log("onExit: " + args);
});
application.on("onLowMemory", function (args) {
console.log("onLowMemory: " + args);
});
application.start(); application.start();

View File

@ -382,7 +382,7 @@ var NativeActivity = {
return this[ANDROID_FRAME]; return this[ANDROID_FRAME];
}, },
onCreate: function(savedInstanceState: android.os.Bundle) { onCreate: function (savedInstanceState: android.os.Bundle) {
trace.write("NativeScriptActivity.onCreate(); savedInstanceState: " + savedInstanceState, trace.categories.NativeLifecycle); trace.write("NativeScriptActivity.onCreate(); savedInstanceState: " + savedInstanceState, trace.categories.NativeLifecycle);
// Find the frame for this activity. // Find the frame for this activity.
@ -418,7 +418,7 @@ var NativeActivity = {
this.frame._onActivityCreated(isRestart); this.frame._onActivityCreated(isRestart);
}, },
onActivityResult: function(requestCode: number, resultCode: number, data: android.content.Intent) { onActivityResult: function (requestCode: number, resultCode: number, data: android.content.Intent) {
this.super.onActivityResult(requestCode, resultCode, data); this.super.onActivityResult(requestCode, resultCode, data);
trace.write("NativeScriptActivity.onActivityResult();", trace.categories.NativeLifecycle); trace.write("NativeScriptActivity.onActivityResult();", trace.categories.NativeLifecycle);
@ -428,7 +428,7 @@ var NativeActivity = {
} }
}, },
onAttachFragment: function(fragment: android.app.Fragment) { onAttachFragment: function (fragment: android.app.Fragment) {
trace.write("NativeScriptActivity.onAttachFragment() : " + fragment.getTag(), trace.categories.NativeLifecycle); trace.write("NativeScriptActivity.onAttachFragment() : " + fragment.getTag(), trace.categories.NativeLifecycle);
this.super.onAttachFragment(fragment); this.super.onAttachFragment(fragment);
@ -439,19 +439,19 @@ var NativeActivity = {
} }
}, },
onStart: function() { onStart: function () {
this.super.onStart(); this.super.onStart();
trace.write("NativeScriptActivity.onStart();", trace.categories.NativeLifecycle); trace.write("NativeScriptActivity.onStart();", trace.categories.NativeLifecycle);
this.frame.onLoaded(); this.frame.onLoaded();
}, },
onStop: function() { onStop: function () {
this.super.onStop(); this.super.onStop();
trace.write("NativeScriptActivity.onStop();", trace.categories.NativeLifecycle); trace.write("NativeScriptActivity.onStop();", trace.categories.NativeLifecycle);
this.frame.onUnloaded(); this.frame.onUnloaded();
}, },
onDestroy: function() { onDestroy: function () {
// TODO: Implement uninitialized(detached) routine // TODO: Implement uninitialized(detached) routine
var frame = this.frame; var frame = this.frame;
frame._onDetached(true); frame._onDetached(true);
@ -467,7 +467,7 @@ var NativeActivity = {
trace.write("NativeScriptActivity.onDestroy();", trace.categories.NativeLifecycle); trace.write("NativeScriptActivity.onDestroy();", trace.categories.NativeLifecycle);
}, },
onOptionsItemSelected: function(menuItem: android.view.IMenuItem) { onOptionsItemSelected: function (menuItem: android.view.IMenuItem) {
if (!this.androidFrame.hasListeners(frameCommon.Frame.androidOptionSelectedEvent)) { if (!this.androidFrame.hasListeners(frameCommon.Frame.androidOptionSelectedEvent)) {
return false; return false;
} }
@ -483,20 +483,22 @@ var NativeActivity = {
return data.handled; return data.handled;
}, },
onBackPressed: function() { onBackPressed: function () {
trace.write("NativeScriptActivity.onBackPressed;", trace.categories.NativeLifecycle); trace.write("NativeScriptActivity.onBackPressed;", trace.categories.NativeLifecycle);
if (!frameCommon.goBack()) { if (!frameCommon.goBack()) {
this.super.onBackPressed(); this.super.onBackPressed();
} }
}, },
onLowMemory: function() { onLowMemory: function () {
gc(); gc();
java.lang.System.gc(); java.lang.System.gc();
this.super.onLowMemory(); this.super.onLowMemory();
application.notify(<application.ApplicationEventData>{ eventName: "onLowMemory", object: this, android: undefined, ios: undefined });
}, },
onTrimMemory: function(level: number) { onTrimMemory: function (level: number) {
gc(); gc();
java.lang.System.gc(); java.lang.System.gc();
this.super.onTrimMemory(level); this.super.onTrimMemory(level);
@ -668,7 +670,7 @@ function findPageForFragment(fragment: android.app.Fragment, frame: Frame) {
} }
function startActivity(activity: android.app.Activity, entry: definition.NavigationEntry) { function startActivity(activity: android.app.Activity, entry: definition.NavigationEntry) {
var intent = new android.content.Intent(activity, (<any>com).tns.NativeScriptActivity.class); var intent = new android.content.Intent(activity,(<any>com).tns.NativeScriptActivity.class);
intent.setAction(android.content.Intent.ACTION_DEFAULT); intent.setAction(android.content.Intent.ACTION_DEFAULT);
// TODO: Put the navigation context (if any) in the intent // TODO: Put the navigation context (if any) in the intent
activity.startActivity(intent); activity.startActivity(intent);