From b113b0021a92616cf617e7a6f56fa1e09edded36 Mon Sep 17 00:00:00 2001 From: Martin Yankov Date: Fri, 9 Feb 2018 16:04:20 +0200 Subject: [PATCH] feat: Add methods to get the root view and set a different root view at run time (#5386) * feat: add option to set a different root view at run time * feat: expose application getRootView method * refactor: Introduce ViewEntry interface * fix: Respect root view rturned from launch event in Android * refactor: getRootView() code + caching root view per activity. * refactor: add app-root.xml in apps * refactor: http test made async --- apps/app/ui-tests-app/app-root.xml | 1 + apps/app/ui-tests-app/app.ts | 33 +-- tests/app/http/http-tests.ts | 26 +-- .../application/application-common.ts | 2 + .../application/application.android.ts | 34 ++- tns-core-modules/application/application.d.ts | 11 + .../application/application.ios.ts | 14 ++ tns-core-modules/ui/builder/builder.ts | 8 +- tns-core-modules/ui/frame/activity.android.ts | 2 +- tns-core-modules/ui/frame/frame.android.ts | 200 +++++++++++------- tns-core-modules/ui/frame/frame.d.ts | 19 +- 11 files changed, 227 insertions(+), 123 deletions(-) create mode 100644 apps/app/ui-tests-app/app-root.xml diff --git a/apps/app/ui-tests-app/app-root.xml b/apps/app/ui-tests-app/app-root.xml new file mode 100644 index 000000000..2ac627182 --- /dev/null +++ b/apps/app/ui-tests-app/app-root.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/app/ui-tests-app/app.ts b/apps/app/ui-tests-app/app.ts index a213f7f9b..535636a81 100644 --- a/apps/app/ui-tests-app/app.ts +++ b/apps/app/ui-tests-app/app.ts @@ -1,13 +1,11 @@ -console.log("####### ------ APP MODULES START ") +console.log("####### ------ APP MODULES START "); import * as application from "tns-core-modules/application"; import * as trace from "tns-core-modules/trace"; +trace.addCategories(trace.categories.NativeLifecycle); +trace.addCategories(trace.categories.Navigation); +trace.addCategories(trace.categories.Transition); trace.enable(); -trace.setCategories(trace.categories.concat( - trace.categories.NativeLifecycle, - trace.categories.Navigation, - trace.categories.Transition - )); var countResume = 0; var countSuspend = 0; @@ -25,7 +23,7 @@ application.on("uncaughtError", args => { } }); -application.on(application.launchEvent, function (args: application.ApplicationEventData) { +application.on(application.launchEvent, function(args: application.LaunchEventData) { if (args.android) { // For Android applications, args.android is an android.content.Intent class. console.log("### Launched application with: " + args.android + "."); @@ -35,7 +33,7 @@ application.on(application.launchEvent, function (args: application.ApplicationE } }); -application.on(application.suspendEvent, function (args: application.ApplicationEventData) { +application.on(application.suspendEvent, function(args: application.ApplicationEventData) { if (args.android) { // For Android applications, args.android is an android activity class. console.log("#" + ++countSuspend + "# SuspendEvent Activity: " + args.android); @@ -45,7 +43,7 @@ application.on(application.suspendEvent, function (args: application.Application } }); -application.on(application.resumeEvent, function (args: application.ApplicationEventData) { +application.on(application.resumeEvent, function(args: application.ApplicationEventData) { if (args.android) { // For Android applications, args.android is an android activity class. console.log("#" + ++countResume + "# ResumeEvent Activity: " + args.android); @@ -55,7 +53,7 @@ application.on(application.resumeEvent, function (args: application.ApplicationE } }); -application.on(application.exitEvent, function (args: application.ApplicationEventData) { +application.on(application.exitEvent, function(args: application.ApplicationEventData) { if (args.android) { // For Android applications, args.android is an android activity class. console.log("### ExitEvent Activity: " + args.android); @@ -65,7 +63,7 @@ application.on(application.exitEvent, function (args: application.ApplicationEve } }); -application.on(application.lowMemoryEvent, function (args: application.ApplicationEventData) { +application.on(application.lowMemoryEvent, function(args: application.ApplicationEventData) { if (args.android) { // For Android applications, args.android is an android activity class. console.log("### LowMemoryEvent Activity: " + args.android); @@ -75,12 +73,15 @@ application.on(application.lowMemoryEvent, function (args: application.Applicati } }); -application.on(application.uncaughtErrorEvent, function (args: application.UnhandledErrorEventData) { - console.log("### NativeScriptError: " + args.error); - console.log("### nativeException: " + (args.error).nativeException); - console.log("### stackTace: " + (args.error).stackTrace); - console.log("### stack: " + args.error.stack); +application.on(application.uncaughtErrorEvent, function(args: application.UnhandledErrorEventData) { + console.log("### NativeScriptError: " + args.error); + console.log("### nativeException: " + (args.error).nativeException); + console.log("### stackTrace: " + (args.error).stackTrace); + console.log("### stack: " + args.error.stack); }); application.setCssFileName("ui-tests-app/app.css"); + application.start({ moduleName: "ui-tests-app/main-page" }); +// application.run({ moduleName: "ui-tests-app/app-root" }); +// application.run(); diff --git a/tests/app/http/http-tests.ts b/tests/app/http/http-tests.ts index 23492ae67..5adbaa4db 100644 --- a/tests/app/http/http-tests.ts +++ b/tests/app/http/http-tests.ts @@ -634,20 +634,12 @@ export var test_request_jsonAsContentSentAndReceivedProperly = function (done) { }; declare var Worker: any; -export var test_getString_WorksProperlyInWorker = function () { - var ready; - - var worker = new Worker("./http-string-worker"); - - worker.onmessage = function (msg) { - TKUnit.assert(typeof msg.data === "string", "Result from getString() should be valid string object!"); - ready = true; - } - - worker.onerror = function (e) { - ready = true; - throw e; - } - - TKUnit.waitUntilReady(() => ready); -} +export var test_getString_WorksProperlyInWorker = function(done) { + let worker = new Worker("./http-string-worker"); + worker.onmessage = function(msg) { + done(); + }; + worker.onerror = function(e) { + done(e); + }; +}; diff --git a/tns-core-modules/application/application-common.ts b/tns-core-modules/application/application-common.ts index dd3a64e21..25434d193 100644 --- a/tns-core-modules/application/application-common.ts +++ b/tns-core-modules/application/application-common.ts @@ -2,6 +2,8 @@ require("globals"); import { Observable, EventData } from "../data/observable"; +// types +import { View } from "../ui/core/view"; import { trace as profilingTrace, time, diff --git a/tns-core-modules/application/application.android.ts b/tns-core-modules/application/application.android.ts index b83737ad0..403132452 100644 --- a/tns-core-modules/application/application.android.ts +++ b/tns-core-modules/application/application.android.ts @@ -13,7 +13,8 @@ import { profile } from "../profiling"; // First reexport so that app module is initialized. export * from "./application-common"; -import { NavigationEntry } from "../ui/frame"; +// types +import { NavigationEntry, View, AndroidActivityCallbacks } from "../ui/frame"; const ActivityCreated = "activityCreated"; const ActivityDestroyed = "activityDestroyed"; @@ -53,7 +54,7 @@ export class AndroidApplication extends Observable implements AndroidApplication if (this.nativeApp === nativeApp) { return; } - + if (this.nativeApp) { throw new Error("application.android already initialized."); } @@ -148,10 +149,35 @@ export function run(entry?: NavigationEntry | string) { start(entry); } +const CALLBACKS = "_callbacks"; + +export function _resetRootView(entry?: NavigationEntry | string) { + const activity = androidApp.foregroundActivity; + if (!activity) { + throw new Error("Cannot find android activity."); + } + + mainEntry = typeof entry === "string" ? { moduleName: entry } : entry; + const callbacks: AndroidActivityCallbacks = activity[CALLBACKS]; + callbacks.resetActivityContent(activity); +} + export function getMainEntry() { return mainEntry; } +export function getRootView() { + // Use start activity as a backup when foregroundActivity is still not set + // in cases when we are getting the root view before activity.onResumed event is fired + const activity = androidApp.foregroundActivity || androidApp.startActivity; + if (!activity) { + return undefined; + } + const callbacks: AndroidActivityCallbacks = activity[CALLBACKS]; + + return callbacks ? callbacks.getRootView() : undefined; +} + export function getNativeApplication(): android.app.Application { // Try getting it from module - check whether application.android.init has been explicitly called let nativeApp = androidApp.nativeApp; @@ -202,11 +228,11 @@ function initLifecycleCallbacks() { } }); - const notifyActivityCreated = profile("notifyActivityCreated", function(activity: android.app.Activity, savedInstanceState: android.os.Bundle) { + const notifyActivityCreated = profile("notifyActivityCreated", function (activity: android.app.Activity, savedInstanceState: android.os.Bundle) { androidApp.notify({ eventName: ActivityCreated, object: androidApp, activity, bundle: savedInstanceState }); }); - const subscribeForGlobalLayout = profile("subscribeForGlobalLayout", function(activity: android.app.Activity) { + const subscribeForGlobalLayout = profile("subscribeForGlobalLayout", function (activity: android.app.Activity) { const rootView = activity.getWindow().getDecorView().getRootView(); let onGlobalLayoutListener = new android.view.ViewTreeObserver.OnGlobalLayoutListener({ onGlobalLayout() { diff --git a/tns-core-modules/application/application.d.ts b/tns-core-modules/application/application.d.ts index 2fc5f7845..99ffa04ba 100644 --- a/tns-core-modules/application/application.d.ts +++ b/tns-core-modules/application/application.d.ts @@ -116,6 +116,11 @@ export interface CssChangedEventData extends EventData { */ export function getMainEntry(): NavigationEntry; +/** + * Get current application root view. + */ +export function getRootView(): View; + /** * Get application level static resources. */ @@ -178,6 +183,12 @@ export function start(entry?: NavigationEntry | string); */ export function run(entry?: NavigationEntry | string); +/** + * Call this method to change the root view of your application. Important: Your application must already be running. + * This method won't create Frame as root view. + */ +export function _resetRootView(entry?: NavigationEntry | string); + //@private /** * Internal method use to check if a root Frame should be automatically created as root view. diff --git a/tns-core-modules/application/application.ios.ts b/tns-core-modules/application/application.ios.ts index 889a7aca8..ac3713969 100644 --- a/tns-core-modules/application/application.ios.ts +++ b/tns-core-modules/application/application.ios.ts @@ -100,6 +100,10 @@ class IOSApplication implements IOSApplicationDefinition { } } + get rootView() : View { + return this._rootView; + } + public addNotificationObserver(notificationName: string, onReceiveCallback: (notification: NSNotification) => void): NotificationObserver { const observer = NotificationObserver.initWithCallback(onReceiveCallback); utils.ios.getter(NSNotificationCenter, NSNotificationCenter.defaultCenter).addObserverSelectorNameObject(observer, "onReceive", notificationName, null); @@ -263,6 +267,10 @@ export function getMainEntry() { return mainEntry; } +export function getRootView() { + return iosApp.rootView; +} + // NOTE: for backwards compatibility. Remove for 4.0.0. let createRootFrame = true; let started: boolean = false; @@ -296,6 +304,12 @@ export function run(entry?: string | NavigationEntry) { start(entry); } +export function _resetRootView(entry?: NavigationEntry | string) { + createRootFrame = false; + mainEntry = typeof entry === "string" ? { moduleName: entry } : entry; + iosApp.setWindowContent(); +} + export function getNativeApplication(): UIApplication { return iosApp.nativeApp; } diff --git a/tns-core-modules/ui/builder/builder.ts b/tns-core-modules/ui/builder/builder.ts index 0989b4f3a..d5d5ca1cc 100644 --- a/tns-core-modules/ui/builder/builder.ts +++ b/tns-core-modules/ui/builder/builder.ts @@ -1,7 +1,7 @@ // Definitions. import { LoadOptions } from "."; import { View, ViewBase, Template, KeyedTemplate } from "../core/view"; -import { NavigationEntry } from "../frame"; +import { ViewEntry } from "../frame"; // Types. import { debug, ScopeError, SourceError, Source } from "../../utils/debug"; @@ -62,7 +62,7 @@ export function loadPage(moduleNamePath: string, fileName: string, context?: any return componentModule && componentModule.component; } -const loadModule = profile("loadModule", (moduleNamePath: string, entry: NavigationEntry): ModuleExports => { +const loadModule = profile("loadModule", (moduleNamePath: string, entry: ViewEntry): ModuleExports => { // web-pack case where developers register their page JS file manually. if (global.moduleExists(entry.moduleName)) { return global.loadModule(entry.moduleName); @@ -94,7 +94,7 @@ const viewFromBuilder = profile("viewFromBuilder", (moduleNamePath: string, modu return null; }) -export const createViewFromEntry = profile("createViewFromEntry", (entry: NavigationEntry): View => { +export const createViewFromEntry = profile("createViewFromEntry", (entry: ViewEntry): View => { if (entry.create) { return createView(entry); } else if (entry.moduleName) { @@ -116,7 +116,7 @@ export const createViewFromEntry = profile("createViewFromEntry", (entry: Naviga throw new Error("Failed to load page XML file for module: " + entry.moduleName); }); -const createView = profile("entry.create", (entry: NavigationEntry): View => { +const createView = profile("entry.create", (entry: ViewEntry): View => { const view = entry.create(); if (!view) { throw new Error("Failed to create Page with entry.create() function."); diff --git a/tns-core-modules/ui/frame/activity.android.ts b/tns-core-modules/ui/frame/activity.android.ts index f09627936..5d935066b 100644 --- a/tns-core-modules/ui/frame/activity.android.ts +++ b/tns-core-modules/ui/frame/activity.android.ts @@ -19,7 +19,7 @@ class NativeScriptActivity extends android.app.Activity { appModule.android.init(this.getApplication()); // Set isNativeScriptActivity in onCreate. - // The JS construcotr might not be called beacuse the activity is created from Andoird. + // The JS constructor might not be called because the activity is created from Android. this.isNativeScriptActivity = true; if (!this._callbacks) { setActivityCallbacks(this); diff --git a/tns-core-modules/ui/frame/frame.android.ts b/tns-core-modules/ui/frame/frame.android.ts index 0c394dff7..ccaa53e13 100644 --- a/tns-core-modules/ui/frame/frame.android.ts +++ b/tns-core-modules/ui/frame/frame.android.ts @@ -25,10 +25,12 @@ import { createViewFromEntry } from "../builder"; export * from "./frame-common"; const INTENT_EXTRA = "com.tns.activity"; +const ROOT_VIEW_ID_EXTRA = "com.tns.activity.rootViewId"; const FRAMEID = "_frameId"; const CALLBACKS = "_callbacks"; const ownerSymbol = Symbol("_owner"); +const activityRootViewsMap = new Map>(); let navDepth = -1; let fragmentId = -1; @@ -73,11 +75,12 @@ function getAttachListener(): android.view.View.OnAttachStateChangeListener { } export function reloadPage(): void { - const app = application.android; - const rootView: View = (app).rootView; + const activity = application.android.foregroundActivity; + const callbacks: AndroidActivityCallbacks = activity[CALLBACKS]; + const rootView: View = callbacks.getRootView(); + if (!rootView || !rootView._onLivesync()) { - // Delete previously cached root view in order to recreate it. - resetActivityContent(application.android.foregroundActivity); + callbacks.resetActivityContent(activity); } } @@ -288,7 +291,7 @@ export class Frame extends FrameBase { const newFragment = this.createFragment(newEntry, newFragmentTag); const transaction = manager.beginTransaction(); const animated = this._getIsAnimatedNavigation(newEntry.entry); - // NOTE: Don't use transition for the initial nagivation (same as on iOS) + // NOTE: Don't use transition for the initial navigation (same as on iOS) // On API 21+ transition won't be triggered unless there was at least one // layout pass so we will wait forever for transitionCompleted handler... // https://github.com/NativeScript/NativeScript/issues/4895 @@ -754,7 +757,11 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks { } class ActivityCallbacksImplementation implements AndroidActivityCallbacks { - public _rootView: View; + private _rootView: View; + + public getRootView(): View { + return this._rootView; + } @profile public onCreate(activity: android.app.Activity, savedInstanceState: android.os.Bundle, superFunc: Function): void { @@ -770,18 +777,29 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks { let isRestart = !!savedInstanceState && moduleLoaded; superFunc.call(activity, isRestart ? savedInstanceState : null); - setActivityContent(activity, savedInstanceState); + // Try to get the rootViewId form the saved state in case the activity + // was destroyed and we are now recreating it. + if (savedInstanceState) { + const rootViewId = savedInstanceState.getInt(ROOT_VIEW_ID_EXTRA, -1); + if (rootViewId !== -1 && activityRootViewsMap.has(rootViewId)) { + this._rootView = activityRootViewsMap.get(rootViewId).get(); + } + } + + this.setActivityContent(activity, savedInstanceState, true); moduleLoaded = true; } @profile public onSaveInstanceState(activity: android.app.Activity, outState: android.os.Bundle, superFunc: Function): void { superFunc.call(activity, outState); - const frame = this._rootView; - if (frame instanceof Frame) { - outState.putInt(INTENT_EXTRA, frame.android.frameId); - frame._saveFragmentsState(); + const rootView = this._rootView; + if (rootView instanceof Frame) { + outState.putInt(INTENT_EXTRA, rootView.android.frameId); + rootView._saveFragmentsState(); } + + outState.putInt(ROOT_VIEW_ID_EXTRA, rootView._domId); } @profile @@ -870,7 +888,13 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks { } @profile - public onRequestPermissionsResult(activity: any, requestCode: number, permissions: Array, grantResults: Array, superFunc: Function): void { + public onRequestPermissionsResult( + activity: any, + requestCode: number, + permissions: Array, + grantResults: Array, + superFunc: Function + ): void { if (traceEnabled()) { traceWrite("NativeScriptActivity.onRequestPermissionsResult;", traceCategories.NativeLifecycle); } @@ -886,7 +910,13 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks { } @profile - public onActivityResult(activity: any, requestCode: number, resultCode: number, data: android.content.Intent, superFunc: Function): void { + public onActivityResult( + activity: any, + requestCode: number, + resultCode: number, + data: android.content.Intent, + superFunc: Function + ): void { superFunc.call(activity, requestCode, resultCode, data); if (traceEnabled()) { traceWrite(`NativeScriptActivity.onActivityResult(${requestCode}, ${resultCode}, ${data})`, traceCategories.NativeLifecycle); @@ -901,78 +931,98 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks { intent: data }); } -} -function resetActivityContent(activity: android.app.Activity): void { - const callbacks: ActivityCallbacksImplementation = activity[CALLBACKS]; - const app = application.android; + public resetActivityContent(activity: android.app.Activity): void { + // Delete previously cached root view in order to recreate it. + this._rootView = null; + this.setActivityContent(activity, null, false); + this._rootView.callLoaded(); + } - // Delete previously cached root view in order to recreate it. - callbacks._rootView = (app).rootView = null; - setActivityContent(activity, null); - callbacks._rootView.callLoaded(); -} + // Paths that go trough this method: + // 1. Application initial start - there is no rootView in callbacks. + // 2. Application revived after Activity is destroyed. this._rootView should have been restored by id in onCreate. + // 3. Livesync if rootView has no custom _onLivesync. this._rootView should have been cleared upfront. Launch event should not fired + // 4. _resetRootView method. this._rootView should have been cleared upfront. Launch event should not fired + private setActivityContent( + activity: android.app.Activity, + savedInstanceState: android.os.Bundle, + fireLaunchEvent: boolean + ): void { + const shouldCreateRootFrame = application.shouldCreateRootFrame(); + let rootView = this._rootView; -function setActivityContent(activity: android.app.Activity, savedInstanceState: android.os.Bundle): void { - const callbacks: ActivityCallbacksImplementation = activity[CALLBACKS]; - - const shouldCreateRootFrame = application.shouldCreateRootFrame(); - const app = application.android; - - // TODO: this won't work if we open more than one activity!!! - let rootView = callbacks._rootView = (app).rootView; - if (!rootView) { - const mainEntry = application.getMainEntry(); - const intent = activity.getIntent(); - rootView = notifyLaunch(intent, savedInstanceState); - if (shouldCreateRootFrame) { - const extras = intent.getExtras(); - let frameId = -1; - - // We have extras when we call - new Frame().navigate(); - // savedInstanceState is used when activity is recreated. - // NOTE: On API 23+ we get extras on first run. - // Check changed - first try to get frameId from Extras if not from saveInstanceState. - if (extras) { - frameId = extras.getInt(INTENT_EXTRA, -1); - } - - if (savedInstanceState && frameId < 0) { - frameId = savedInstanceState.getInt(INTENT_EXTRA, -1); - } - - if (!rootView) { - // If we have frameId from extras - we are starting a new activity from navigation (e.g. new Frame().navigate())) - // Then we check if we have frameId from savedInstanceState - this happens when Activity is destroyed but app was not (e.g. suspend) - rootView = getFrameById(frameId) || new Frame(); - } - - if (rootView instanceof Frame) { - rootView.navigate(mainEntry); - } else { - throw new Error("A Frame must be used to navigate to a Page."); - } - } else { - rootView = createViewFromEntry(mainEntry); + if (traceEnabled()) { + traceWrite( + `Frame.setActivityContent rootView: ${rootView} shouldCreateRootFrame: ${shouldCreateRootFrame} fireLaunchEvent: ${fireLaunchEvent}`, + traceCategories.NativeLifecycle + ); } - callbacks._rootView = (app).rootView = rootView; - } + if (!rootView) { + const mainEntry = application.getMainEntry(); + const intent = activity.getIntent(); - // Initialize native visual tree; - if (shouldCreateRootFrame) { - // Don't setup as styleScopeHost - rootView._setupUI(activity); - } else { - // setup view as styleScopeHost - rootView._setupAsRootView(activity); - } + if (fireLaunchEvent) { + rootView = notifyLaunch(intent, savedInstanceState); + } - activity.setContentView(rootView.nativeViewProtected, new org.nativescript.widgets.CommonLayoutParams()); + if (shouldCreateRootFrame) { + const extras = intent.getExtras(); + let frameId = -1; + + // We have extras when we call - new Frame().navigate(); + // savedInstanceState is used when activity is recreated. + // NOTE: On API 23+ we get extras on first run. + // Check changed - first try to get frameId from Extras if not from saveInstanceState. + if (extras) { + frameId = extras.getInt(INTENT_EXTRA, -1); + } + + if (savedInstanceState && frameId < 0) { + frameId = savedInstanceState.getInt(INTENT_EXTRA, -1); + } + + if (!rootView) { + // If we have frameId from extras - we are starting a new activity from navigation (e.g. new Frame().navigate())) + // Then we check if we have frameId from savedInstanceState - this happens when Activity is destroyed but app was not (e.g. suspend) + rootView = getFrameById(frameId) || new Frame(); + } + + if (rootView instanceof Frame) { + rootView.navigate(mainEntry); + } else { + throw new Error("A Frame must be used to navigate to a Page."); + } + } else { + // Create the root view if the notifyLaunch didn't return it + rootView = rootView || createViewFromEntry(mainEntry); + } + + this._rootView = rootView; + activityRootViewsMap.set(rootView._domId, new WeakRef(rootView)); + } + + // Initialize native visual tree; + if (shouldCreateRootFrame) { + // Don't setup as styleScopeHost + rootView._setupUI(activity); + } else { + // setup view as styleScopeHost + rootView._setupAsRootView(activity); + } + + activity.setContentView(rootView.nativeViewProtected, new org.nativescript.widgets.CommonLayoutParams()); + } } const notifyLaunch = profile("notifyLaunch", function notifyLaunch(intent: android.content.Intent, savedInstanceState: android.os.Bundle): View { - const launchArgs: application.LaunchEventData = { eventName: application.launchEvent, object: application.android, android: intent, savedInstanceState }; + const launchArgs: application.LaunchEventData = { + eventName: application.launchEvent, + object: application.android, + android: intent, savedInstanceState + }; + application.notify(launchArgs); application.notify({ eventName: "loadAppCss", object: this, cssFile: application.getCssFileName() }); return launchArgs.root; diff --git a/tns-core-modules/ui/frame/frame.d.ts b/tns-core-modules/ui/frame/frame.d.ts index d60edefdf..2ac13eb27 100644 --- a/tns-core-modules/ui/frame/frame.d.ts +++ b/tns-core-modules/ui/frame/frame.d.ts @@ -187,19 +187,23 @@ export function goBack(); export function stack(): Array; /** - * Represents an entry in passed to navigate method. + * Represents an entry to be used to create a view or load it form file */ -export interface NavigationEntry { +export interface ViewEntry { /** - * The name of the module containing the Page instance to load. Optional. + * The name of the module containing the View instance to load. Optional. */ moduleName?: string; /** - * A function used to create the Page instance. Optional. + * A function used to create the View instance. Optional. */ - create?: () => Page; - + create?: () => View; +} +/** + * Represents an entry in passed to navigate method. + */ +export interface NavigationEntry extends ViewEntry { /** * An object passed to the onNavigatedTo callback of the Page. Typically this is used to pass some data among pages. Optional. */ @@ -377,6 +381,9 @@ export interface AndroidFrame extends Observable { } export interface AndroidActivityCallbacks { + getRootView(): View; + resetActivityContent(activity: any): void; + onCreate(activity: any, savedInstanceState: any, superFunc: Function): void; onSaveInstanceState(activity: any, outState: any, superFunc: Function): void; onStart(activity: any, superFunc: Function): void;