mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 03:31:45 +08:00
FrameClass implemented as TypeScript class
NativeActivity is now NativeScriptActivity and is real class Added NativeScriptApplication class Added JavaProxy attribute to FrameClass, NativeScriptActivity & NativeScriptApplication
This commit is contained in:
@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">12.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
<TypeScriptToolsVersion>1.7</TypeScriptToolsVersion>
|
||||
<TypeScriptToolsVersion>1.8</TypeScriptToolsVersion>
|
||||
<ProjectGuid>{2313F1BF-1F2D-4F11-806A-87927FA6A7C0}</ProjectGuid>
|
||||
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
|
@ -8,6 +8,34 @@ import * as fileResolverModule from "file-system/file-name-resolver";
|
||||
global.moduleMerge(appModule, exports);
|
||||
var typedExports: typeof definition = exports;
|
||||
|
||||
@JavaProxy("com.tns.NativeScriptApplication")
|
||||
class NativeScriptApplication extends android.app.Application {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
public onCreate(): void {
|
||||
androidApp.init(this);
|
||||
setupOrientationListener(androidApp);
|
||||
}
|
||||
|
||||
public onLowMemory(): void {
|
||||
gc();
|
||||
java.lang.System.gc();
|
||||
super.onLowMemory();
|
||||
|
||||
typedExports.notify(<definition.ApplicationEventData>{ eventName: typedExports.lowMemoryEvent, object: this, android: this });
|
||||
}
|
||||
|
||||
public onTrimMemory(level: number): void {
|
||||
gc();
|
||||
java.lang.System.gc();
|
||||
super.onTrimMemory(level);
|
||||
}
|
||||
}
|
||||
|
||||
// We are using the exports object for the common events since we merge the appModule with this module's exports, which is what users will receive when require("application") is called;
|
||||
// TODO: This is kind of hacky and is "pure JS in TypeScript"
|
||||
|
||||
@ -15,13 +43,8 @@ function initEvents() {
|
||||
// TODO: Verify whether the logic for triggerring application-wide events based on Activity callbacks is working properly
|
||||
var lifecycleCallbacks = new android.app.Application.ActivityLifecycleCallbacks({
|
||||
onActivityCreated: function (activity: any, bundle: any) {
|
||||
if (!(activity instanceof (<any>com).tns.NativeScriptActivity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!androidApp.startActivity) {
|
||||
androidApp.startActivity = activity;
|
||||
|
||||
androidApp.notify(<definition.AndroidActivityBundleEventData>{ eventName: "activityCreated", object: androidApp, activity: activity, bundle: bundle });
|
||||
|
||||
if (androidApp.onActivityCreated) {
|
||||
@ -33,9 +56,6 @@ function initEvents() {
|
||||
},
|
||||
|
||||
onActivityDestroyed: function (activity: any) {
|
||||
if (!(activity instanceof (<any>com).tns.NativeScriptActivity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear the current activity reference to prevent leak
|
||||
if (activity === androidApp.foregroundActivity) {
|
||||
@ -67,10 +87,6 @@ function initEvents() {
|
||||
},
|
||||
|
||||
onActivityPaused: function (activity: any) {
|
||||
if (!(activity instanceof (<any>com).tns.NativeScriptActivity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
androidApp.paused = true;
|
||||
|
||||
if (activity === androidApp.foregroundActivity) {
|
||||
@ -89,10 +105,6 @@ function initEvents() {
|
||||
},
|
||||
|
||||
onActivityResumed: function (activity: any) {
|
||||
if (!(activity instanceof (<any>com).tns.NativeScriptActivity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
androidApp.paused = false;
|
||||
|
||||
if (activity === androidApp.foregroundActivity) {
|
||||
@ -111,10 +123,6 @@ function initEvents() {
|
||||
},
|
||||
|
||||
onActivitySaveInstanceState: function (activity: any, bundle: any) {
|
||||
if (!(activity instanceof (<any>com).tns.NativeScriptActivity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
androidApp.notify(<definition.AndroidActivityBundleEventData>{ eventName: "saveActivityState", object: androidApp, activity: activity, bundle: bundle });
|
||||
|
||||
if (androidApp.onSaveActivityState) {
|
||||
@ -123,10 +131,6 @@ function initEvents() {
|
||||
},
|
||||
|
||||
onActivityStarted: function (activity: any) {
|
||||
if (!(activity instanceof (<any>com).tns.NativeScriptActivity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
androidApp.foregroundActivity = activity;
|
||||
|
||||
androidApp.notify(<definition.AndroidActivityEventData>{ eventName: "activityStarted", object: androidApp, activity: activity });
|
||||
@ -137,10 +141,6 @@ function initEvents() {
|
||||
},
|
||||
|
||||
onActivityStopped: function (activity: any) {
|
||||
if (!(activity instanceof (<any>com).tns.NativeScriptActivity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
androidApp.notify(<definition.AndroidActivityEventData>{ eventName: "activityStopped", object: androidApp, activity: activity });
|
||||
|
||||
if (androidApp.onActivityStopped) {
|
||||
@ -152,7 +152,7 @@ function initEvents() {
|
||||
return lifecycleCallbacks;
|
||||
}
|
||||
|
||||
export class AndroidApplication extends observable.Observable implements definition.AndroidApplication {
|
||||
class AndroidApplication extends observable.Observable implements definition.AndroidApplication {
|
||||
public static activityCreatedEvent = "activityCreated";
|
||||
public static activityDestroyedEvent = "activityDestroyed";
|
||||
public static activityStartedEvent = "activityStarted";
|
||||
@ -190,10 +190,6 @@ export class AndroidApplication extends observable.Observable implements definit
|
||||
|
||||
private _eventsToken: any;
|
||||
|
||||
public getActivity(intent: android.content.Intent): Object {
|
||||
return frame.getActivity();
|
||||
}
|
||||
|
||||
public init(nativeApp: any) {
|
||||
this.nativeApp = nativeApp;
|
||||
this.packageName = nativeApp.getPackageName();
|
||||
@ -245,6 +241,10 @@ export class AndroidApplication extends observable.Observable implements definit
|
||||
}
|
||||
}
|
||||
|
||||
var androidApp = new AndroidApplication();
|
||||
// use the exports object instead of 'export var' due to global namespace collision
|
||||
typedExports.android = androidApp;
|
||||
|
||||
var BroadcastReceiverClass;
|
||||
function ensureBroadCastReceiverClass() {
|
||||
if (BroadcastReceiverClass) {
|
||||
@ -270,21 +270,6 @@ function ensureBroadCastReceiverClass() {
|
||||
BroadcastReceiverClass = BroadcastReceiver;
|
||||
}
|
||||
|
||||
global.__onUncaughtError = function (error: definition.NativeScriptError) {
|
||||
var types: typeof typesModule = require("utils/types");
|
||||
|
||||
// TODO: Obsolete this
|
||||
if (types.isFunction(typedExports.onUncaughtError)) {
|
||||
typedExports.onUncaughtError(error);
|
||||
}
|
||||
|
||||
typedExports.notify({ eventName: typedExports.uncaughtErrorEvent, object: appModule.android, android: error });
|
||||
}
|
||||
|
||||
function loadCss() {
|
||||
typedExports.cssSelectorsCache = typedExports.loadCss(typedExports.cssFile);
|
||||
}
|
||||
|
||||
var started = false;
|
||||
export function start(entry?: frame.NavigationEntry) {
|
||||
if (started) {
|
||||
@ -292,31 +277,13 @@ export function start(entry?: frame.NavigationEntry) {
|
||||
}
|
||||
|
||||
started = true;
|
||||
|
||||
if (entry) {
|
||||
typedExports.mainEntry = entry;
|
||||
}
|
||||
|
||||
// this should be the first call, to avoid issues when someone accesses the Application singleton prior to extending its onCreate method
|
||||
app.init({
|
||||
getActivity: function (activity: android.app.Activity) {
|
||||
var intent = activity.getIntent()
|
||||
return androidApp.getActivity(intent);
|
||||
},
|
||||
|
||||
onCreate: function () {
|
||||
androidApp.init(this);
|
||||
setupOrientationListener(androidApp);
|
||||
}
|
||||
});
|
||||
|
||||
loadCss();
|
||||
}
|
||||
|
||||
var androidApp = new AndroidApplication();
|
||||
// use the exports object instead of 'export var' due to global namespace collision
|
||||
typedExports.android = androidApp;
|
||||
|
||||
var currentOrientation: number;
|
||||
function setupOrientationListener(androidApp: AndroidApplication) {
|
||||
androidApp.registerBroadcastReceiver(android.content.Intent.ACTION_CONFIGURATION_CHANGED, onConfigurationChanged);
|
||||
@ -353,6 +320,10 @@ function onConfigurationChanged(context: android.content.Context, intent: androi
|
||||
}
|
||||
}
|
||||
|
||||
function loadCss() {
|
||||
typedExports.cssSelectorsCache = typedExports.loadCss(typedExports.cssFile);
|
||||
}
|
||||
|
||||
global.__onLiveSync = function () {
|
||||
if (typedExports.android && typedExports.android.paused) {
|
||||
return;
|
||||
@ -369,3 +340,14 @@ global.__onLiveSync = function () {
|
||||
// Reload current page.
|
||||
frame.reloadPage();
|
||||
}
|
||||
|
||||
global.__onUncaughtError = function (error: definition.NativeScriptError) {
|
||||
var types: typeof typesModule = require("utils/types");
|
||||
|
||||
// TODO: Obsolete this
|
||||
if (types.isFunction(typedExports.onUncaughtError)) {
|
||||
typedExports.onUncaughtError(error);
|
||||
}
|
||||
|
||||
typedExports.notify({ eventName: typedExports.uncaughtErrorEvent, object: appModule.android, android: error });
|
||||
}
|
7
application/application.d.ts
vendored
7
application/application.d.ts
vendored
@ -347,13 +347,6 @@ declare module "application" {
|
||||
*/
|
||||
paused: boolean;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Returns com.tns.NativeScriptActivity.extend implementation.
|
||||
*/
|
||||
getActivity(intent: any /* android.content.Intent */): any;
|
||||
|
||||
/**
|
||||
* [Deprecated. Please use the respective event instead.] Direct handler of the [onActivityCreated method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
|
||||
*/
|
||||
|
6
declarations.d.ts
vendored
6
declarations.d.ts
vendored
@ -105,6 +105,12 @@ declare var require: NativeScriptRequire;
|
||||
declare function Deprecated(target: Object, key?: string | symbol, value?: any): void;
|
||||
declare function Experimental(target: Object, key?: string | symbol, value?: any): void;
|
||||
|
||||
/**
|
||||
* Decorates class that extends native Java class
|
||||
* @param nativeClassName The name of the newly generated class. Must be unique in the application.
|
||||
*/
|
||||
declare function JavaProxy(nativeClassName: string): ClassDecorator;
|
||||
|
||||
declare function Log(data: any): void;
|
||||
declare function log(data: any): void;
|
||||
declare function float(num: number): any;
|
||||
|
@ -102,7 +102,7 @@ if (platform.device.os === platform.platformNames.android) {
|
||||
|
||||
if (typeof global.__decorate !== "function") {
|
||||
global.__decorate = function (decorators, target, key, desc) {
|
||||
var c = arguments.length
|
||||
var c = arguments.length;
|
||||
var r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
|
||||
if (typeof global.Reflect === "object" && typeof global.Reflect.decorate === "function") {
|
||||
|
@ -25,110 +25,7 @@ var navDepth = -1;
|
||||
|
||||
var activityInitialized = false;
|
||||
|
||||
var animationFixed;
|
||||
function ensureAnimationFixed() {
|
||||
if (!animationFixed) {
|
||||
animationFixed = android.os.Build.VERSION.SDK_INT >= 19 // android.os.Build.VERSION.KITKAT but we don't have definition for it
|
||||
? 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
var FragmentClass;
|
||||
function ensureFragmentClass() {
|
||||
if (FragmentClass) {
|
||||
return;
|
||||
}
|
||||
|
||||
FragmentClass = (<any>android.app.Fragment).extend({
|
||||
|
||||
onCreate: function (savedInstanceState: android.os.Bundle) {
|
||||
trace.write(`${this.getTag()}.onCreate(${savedInstanceState})`, trace.categories.NativeLifecycle);
|
||||
this.super.onCreate(savedInstanceState);
|
||||
this.super.setHasOptionsMenu(true);
|
||||
|
||||
// There is no entry set to the fragment, so this must be destroyed fragment that was recreated by Android.
|
||||
// We should find its corresponding page in our backstack and set it manually.
|
||||
if (!(<any>this).entry) {
|
||||
let frameId = (<android.app.Fragment>this).getArguments().getInt(FRAMEID);
|
||||
let frame = getFrameById(frameId);
|
||||
if (frame) {
|
||||
this.frame = frame;
|
||||
}
|
||||
else {
|
||||
throw new Error(`Cannot find Frame for ${this}`);
|
||||
}
|
||||
|
||||
findPageForFragment(this, this.frame);
|
||||
}
|
||||
},
|
||||
|
||||
onCreateView: function (inflater: android.view.LayoutInflater, container: android.view.ViewGroup, savedInstanceState: android.os.Bundle): android.view.View {
|
||||
trace.write(`${this.getTag()}.onCreateView(inflater, container, ${savedInstanceState})`, trace.categories.NativeLifecycle);
|
||||
var entry = this.entry;
|
||||
var page = entry.resolvedPage;
|
||||
if (savedInstanceState && savedInstanceState.getBoolean(HIDDEN, false)) {
|
||||
this.super.getFragmentManager().beginTransaction().hide(this).commit();
|
||||
page._onAttached(this.getActivity());
|
||||
}
|
||||
else {
|
||||
onFragmentShown(this);
|
||||
}
|
||||
|
||||
return page._nativeView;
|
||||
},
|
||||
|
||||
onHiddenChanged: function (hidden: boolean) {
|
||||
trace.write(`${this.getTag()}.onHiddenChanged(${hidden})`, trace.categories.NativeLifecycle);
|
||||
this.super.onHiddenChanged(hidden);
|
||||
if (hidden) {
|
||||
onFragmentHidden(this);
|
||||
}
|
||||
else {
|
||||
onFragmentShown(this);
|
||||
}
|
||||
},
|
||||
|
||||
onSaveInstanceState: function (outState: android.os.Bundle) {
|
||||
trace.write(`${this.getTag()}.onSaveInstanceState(${outState})`, trace.categories.NativeLifecycle);
|
||||
this.super.onSaveInstanceState(outState);
|
||||
if (this.isHidden()) {
|
||||
outState.putBoolean(HIDDEN, true);
|
||||
}
|
||||
},
|
||||
|
||||
onDestroyView: function () {
|
||||
trace.write(`${this.getTag()}.onDestroyView()`, trace.categories.NativeLifecycle);
|
||||
this.super.onDestroyView();
|
||||
onFragmentHidden(this);
|
||||
|
||||
// When Fragment is destroyed we detach page even if cachePagesOnNavigate is true.
|
||||
let entry: definition.BackstackEntry = this.entry;
|
||||
let page = entry.resolvedPage;
|
||||
if (page._context) {
|
||||
page._onDetached(true);
|
||||
}
|
||||
},
|
||||
|
||||
onDestroy: function () {
|
||||
trace.write(`${this.getTag()}.onDestroy()`, trace.categories.NativeLifecycle);
|
||||
this.super.onDestroy();
|
||||
utils.GC();
|
||||
},
|
||||
|
||||
onCreateAnimator: function (transit: number, enter: boolean, nextAnim: number): android.animation.Animator {
|
||||
var animator = transitionModule._onFragmentCreateAnimator(this, nextAnim);
|
||||
|
||||
if (!animator) {
|
||||
animator = this.super.onCreateAnimator(transit, enter, nextAnim);
|
||||
}
|
||||
|
||||
trace.write(`${this.getTag()}.onCreateAnimator(${transit}, ${enter}, ${nextAnim}): ${animator}`, trace.categories.NativeLifecycle);
|
||||
return animator;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onFragmentShown(fragment) {
|
||||
function onFragmentShown(fragment: FragmentClass) {
|
||||
trace.write(`SHOWN ${fragment.getTag()}`, trace.categories.NativeLifecycle);
|
||||
if (fragment[CLEARING_HISTORY]) {
|
||||
trace.write(`${fragment.getTag()} has been shown, but we are currently clearing history. Returning.`, trace.categories.NativeLifecycle);
|
||||
@ -142,7 +39,7 @@ function onFragmentShown(fragment) {
|
||||
var page: pages.Page = entry.resolvedPage;
|
||||
|
||||
let currentNavigationContext;
|
||||
let navigationQueue = frame._navigationQueue;
|
||||
let navigationQueue = (<any>frame)._navigationQueue;
|
||||
for (let i = 0; i < navigationQueue.length; i++) {
|
||||
if (navigationQueue[i].entry === entry) {
|
||||
currentNavigationContext = navigationQueue[i];
|
||||
@ -165,7 +62,7 @@ function onFragmentShown(fragment) {
|
||||
transitionModule._onFragmentShown(fragment, isBack);
|
||||
}
|
||||
|
||||
function onFragmentHidden(fragment) {
|
||||
function onFragmentHidden(fragment: FragmentClass) {
|
||||
trace.write(`HIDDEN ${fragment.getTag()}`, trace.categories.NativeLifecycle);
|
||||
|
||||
if (fragment[CLEARING_HISTORY]) {
|
||||
@ -281,7 +178,6 @@ export class Frame extends frameCommon.Frame {
|
||||
}
|
||||
|
||||
var newFragmentTag = "fragment" + navDepth;
|
||||
ensureFragmentClass();
|
||||
let newFragment = new FragmentClass();
|
||||
|
||||
let args = new android.os.Bundle();
|
||||
@ -454,178 +350,6 @@ export class Frame extends frameCommon.Frame {
|
||||
}
|
||||
}
|
||||
|
||||
var NativeActivity = {
|
||||
|
||||
get rootView(): View {
|
||||
return this[ROOT_VIEW];
|
||||
},
|
||||
|
||||
onCreate: function (savedInstanceState: android.os.Bundle) {
|
||||
trace.write(`NativeScriptActivity.onCreate(${savedInstanceState})`, trace.categories.NativeLifecycle);
|
||||
|
||||
let app = application.android;
|
||||
let activity: android.app.Activity = this;
|
||||
let intent = activity.getIntent();
|
||||
if (application.onLaunch) {
|
||||
application.onLaunch(intent);
|
||||
}
|
||||
|
||||
let args: application.LaunchEventData = { eventName: application.launchEvent, object: app, android: intent };
|
||||
application.notify(args);
|
||||
|
||||
let frameId = -1;
|
||||
let rootView = args.root;
|
||||
let extras = intent.getExtras();
|
||||
|
||||
// We have extras when we call - new Frame().navigate();
|
||||
// savedInstanceState is used when activity is recreated.
|
||||
if (extras) {
|
||||
frameId = extras.getInt(INTENT_EXTRA, -1);
|
||||
}
|
||||
else if (savedInstanceState) {
|
||||
frameId = savedInstanceState.getInt(INTENT_EXTRA, -1)
|
||||
}
|
||||
|
||||
// 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)
|
||||
// Only then we fallback to the view returned from the event. This is done in order to have backwards compatibility (remove it for 2.0.0).
|
||||
let frame: Frame;
|
||||
let navParam;
|
||||
if (frameId >= 0) {
|
||||
rootView = getFrameById(frameId);
|
||||
}
|
||||
else if (!rootView) {
|
||||
navParam = application.mainEntry;
|
||||
if (!navParam) {
|
||||
navParam = application.mainModule;
|
||||
}
|
||||
|
||||
if (navParam) {
|
||||
frame = new Frame();
|
||||
} else {
|
||||
// TODO: Throw an exception?
|
||||
throw new Error("A Frame must be used to navigate to a Page.");
|
||||
}
|
||||
|
||||
rootView = frame;
|
||||
}
|
||||
|
||||
// If there is savedInstanceState this call will recreate all fragments that were previously in the navigation.
|
||||
// We take care of associating them with a Page from our backstack in the onAttachFragment callback.
|
||||
// If there is savedInstanceState and activityInitialized is false we are restarted but process was killed.
|
||||
// For now we treat it like first run (e.g. we are not passing savedInstanceState so no fragments are being restored).
|
||||
// When we add support for application save/load state - revise this logic.
|
||||
var isRestart = !!savedInstanceState && activityInitialized;
|
||||
this.super.onCreate(isRestart ? savedInstanceState : null);
|
||||
|
||||
this[ROOT_VIEW] = rootView;
|
||||
|
||||
// Initialize native visual tree;
|
||||
rootView._onAttached(this);
|
||||
this.setContentView(rootView._nativeView, new org.nativescript.widgets.CommonLayoutParams());
|
||||
// frameId is negative w
|
||||
if (frame) {
|
||||
frame.navigate(navParam);
|
||||
}
|
||||
|
||||
activityInitialized = true;
|
||||
// TODO: If the above fails because we call fragmentManager.beginTransition().commit() before
|
||||
// we are added as content to activity - add if (rootview instanceof Frame) -> call navigate
|
||||
//this.frame._onActivityCreated(isRestart);
|
||||
},
|
||||
|
||||
onSaveInstanceState(outState: android.os.Bundle): void {
|
||||
this.super.onSaveInstanceState(outState);
|
||||
let view = this.rootView;
|
||||
if (view instanceof Frame) {
|
||||
outState.putInt(INTENT_EXTRA, (<Frame>view).android.frameId);
|
||||
}
|
||||
},
|
||||
|
||||
onActivityResult: function (requestCode: number, resultCode: number, data: android.content.Intent) {
|
||||
this.super.onActivityResult(requestCode, resultCode, data);
|
||||
trace.write(`NativeScriptActivity.onActivityResult(${requestCode}, ${resultCode}, ${data})`, trace.categories.NativeLifecycle);
|
||||
|
||||
var result = application.android.onActivityResult;
|
||||
if (result) {
|
||||
result(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
application.android.notify(<application.AndroidActivityResultEventData>{
|
||||
eventName: "activityResult",
|
||||
object: application.android,
|
||||
activity: this,
|
||||
requestCode: requestCode,
|
||||
resultCode: resultCode,
|
||||
intent: data
|
||||
});
|
||||
},
|
||||
|
||||
onStart: function () {
|
||||
this.super.onStart();
|
||||
trace.write("NativeScriptActivity.onStart();", trace.categories.NativeLifecycle);
|
||||
let rootView: View = this.rootView
|
||||
if (rootView && !rootView.isLoaded) {
|
||||
rootView.onLoaded();
|
||||
}
|
||||
},
|
||||
|
||||
onStop: function () {
|
||||
this.super.onStop();
|
||||
trace.write("NativeScriptActivity.onStop();", trace.categories.NativeLifecycle);
|
||||
let rootView: View = this.rootView
|
||||
if (rootView && rootView.isLoaded) {
|
||||
rootView.onUnloaded();
|
||||
}
|
||||
},
|
||||
|
||||
onDestroy: function () {
|
||||
let rootView: View = this.rootView
|
||||
if (rootView && rootView._context) {
|
||||
rootView._onDetached(true);
|
||||
}
|
||||
|
||||
this.super.onDestroy();
|
||||
trace.write("NativeScriptActivity.onDestroy();", trace.categories.NativeLifecycle);
|
||||
},
|
||||
|
||||
onBackPressed: function () {
|
||||
trace.write("NativeScriptActivity.onBackPressed;", trace.categories.NativeLifecycle);
|
||||
|
||||
var args = <application.AndroidActivityBackPressedEventData>{
|
||||
eventName: "activityBackPressed",
|
||||
object: application.android,
|
||||
activity: this,
|
||||
cancel: false,
|
||||
};
|
||||
application.android.notify(args);
|
||||
|
||||
if (args.cancel) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!frameCommon.goBack()) {
|
||||
this.super.onBackPressed();
|
||||
}
|
||||
},
|
||||
|
||||
onLowMemory: function () {
|
||||
trace.write("NativeScriptActivity.onLowMemory()", trace.categories.NativeLifecycle);
|
||||
gc();
|
||||
java.lang.System.gc();
|
||||
this.super.onLowMemory();
|
||||
|
||||
application.notify(<application.ApplicationEventData>{ eventName: application.lowMemoryEvent, object: this, android: this });
|
||||
},
|
||||
|
||||
onTrimMemory: function (level: number) {
|
||||
trace.write(`NativeScriptActivity.onTrimMemory(${level})`, trace.categories.NativeLifecycle);
|
||||
gc();
|
||||
java.lang.System.gc();
|
||||
this.super.onTrimMemory(level);
|
||||
}
|
||||
};
|
||||
|
||||
var framesCounter = 0;
|
||||
var framesCache: Array<WeakRef<AndroidFrame>> = new Array<WeakRef<AndroidFrame>>();
|
||||
|
||||
@ -803,6 +527,260 @@ function getFrameById(frameId: number): Frame {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getActivity(): Object {
|
||||
return NativeActivity;
|
||||
var animationFixed;
|
||||
function ensureAnimationFixed() {
|
||||
if (!animationFixed) {
|
||||
// android.os.Build.VERSION.KITKAT but we don't have definition for it
|
||||
animationFixed = android.os.Build.VERSION.SDK_INT >= 19 ? 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
@JavaProxy("com.tns.FragmentClass")
|
||||
class FragmentClass extends android.app.Fragment {
|
||||
public frame: Frame;
|
||||
public entry: definition.BackstackEntry;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
public onHiddenChanged(hidden: boolean): void {
|
||||
trace.write(`${this.getTag()}.onHiddenChanged(${hidden})`, trace.categories.NativeLifecycle);
|
||||
super.onHiddenChanged(hidden);
|
||||
if (hidden) {
|
||||
onFragmentHidden(this);
|
||||
}
|
||||
else {
|
||||
onFragmentShown(this);
|
||||
}
|
||||
}
|
||||
|
||||
public onCreateAnimator(transit: number, enter: boolean, nextAnim: number): android.animation.Animator {
|
||||
var animator = transitionModule._onFragmentCreateAnimator(this, nextAnim);
|
||||
if (!animator) {
|
||||
animator = super.onCreateAnimator(transit, enter, nextAnim);
|
||||
}
|
||||
|
||||
trace.write(`${this.getTag()}.onCreateAnimator(${transit}, ${enter}, ${nextAnim}): ${animator}`, trace.categories.NativeLifecycle);
|
||||
return animator;
|
||||
}
|
||||
|
||||
public onCreate(savedInstanceState: android.os.Bundle): void {
|
||||
trace.write(`${this.getTag()}.onCreate(${savedInstanceState})`, trace.categories.NativeLifecycle);
|
||||
super.onCreate(savedInstanceState);
|
||||
super.setHasOptionsMenu(true);
|
||||
|
||||
// There is no entry set to the fragment, so this must be destroyed fragment that was recreated by Android.
|
||||
// We should find its corresponding page in our backstack and set it manually.
|
||||
if (!this.entry) {
|
||||
let frameId = this.getArguments().getInt(FRAMEID);
|
||||
let frame = getFrameById(frameId);
|
||||
if (frame) {
|
||||
this.frame = frame;
|
||||
}
|
||||
else {
|
||||
throw new Error(`Cannot find Frame for ${this}`);
|
||||
}
|
||||
|
||||
findPageForFragment(this, this.frame);
|
||||
}
|
||||
}
|
||||
|
||||
public onCreateView(inflater: android.view.LayoutInflater, container: android.view.ViewGroup, savedInstanceState: android.os.Bundle): android.view.View {
|
||||
trace.write(`${this.getTag()}.onCreateView(inflater, container, ${savedInstanceState})`, trace.categories.NativeLifecycle);
|
||||
var entry = this.entry;
|
||||
var page = entry.resolvedPage;
|
||||
if (savedInstanceState && savedInstanceState.getBoolean(HIDDEN, false)) {
|
||||
this.getFragmentManager().beginTransaction().hide(this).commit();
|
||||
page._onAttached(this.getActivity());
|
||||
}
|
||||
else {
|
||||
onFragmentShown(this);
|
||||
}
|
||||
|
||||
return page._nativeView;
|
||||
}
|
||||
|
||||
public onSaveInstanceState(outState: android.os.Bundle): void {
|
||||
trace.write(`${this.getTag()}.onSaveInstanceState(${outState})`, trace.categories.NativeLifecycle);
|
||||
super.onSaveInstanceState(outState);
|
||||
if (this.isHidden()) {
|
||||
outState.putBoolean(HIDDEN, true);
|
||||
}
|
||||
}
|
||||
|
||||
public onDestroyView(): void {
|
||||
trace.write(`${this.getTag()}.onDestroyView()`, trace.categories.NativeLifecycle);
|
||||
super.onDestroyView();
|
||||
onFragmentHidden(this);
|
||||
|
||||
// When Fragment is destroyed we detach page even if cachePagesOnNavigate is true.
|
||||
let entry = this.entry;
|
||||
let page = entry.resolvedPage;
|
||||
if (page._context) {
|
||||
page._onDetached(true);
|
||||
}
|
||||
}
|
||||
|
||||
public onDestroy(): void {
|
||||
trace.write(`${this.getTag()}.onDestroy()`, trace.categories.NativeLifecycle);
|
||||
super.onDestroy();
|
||||
utils.GC();
|
||||
}
|
||||
}
|
||||
|
||||
@JavaProxy("com.tns.NativeScriptActivity")
|
||||
class NativeScriptActivity extends android.app.Activity {
|
||||
private rootView: View;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
protected onCreate(savedInstanceState: android.os.Bundle): void {
|
||||
trace.write(`NativeScriptActivity.onCreate(${savedInstanceState})`, trace.categories.NativeLifecycle);
|
||||
|
||||
let app = application.android;
|
||||
let intent = this.getIntent();
|
||||
if (application.onLaunch) {
|
||||
application.onLaunch(intent);
|
||||
}
|
||||
|
||||
let args: application.LaunchEventData = { eventName: application.launchEvent, object: app, android: intent };
|
||||
application.notify(args);
|
||||
|
||||
let frameId = -1;
|
||||
let rootView = args.root;
|
||||
let extras = intent.getExtras();
|
||||
|
||||
// We have extras when we call - new Frame().navigate();
|
||||
// savedInstanceState is used when activity is recreated.
|
||||
if (extras) {
|
||||
frameId = extras.getInt(INTENT_EXTRA, -1);
|
||||
}
|
||||
else if (savedInstanceState) {
|
||||
frameId = savedInstanceState.getInt(INTENT_EXTRA, -1)
|
||||
}
|
||||
|
||||
// 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)
|
||||
// Only then we fallback to the view returned from the event. This is done in order to have backwards compatibility (remove it for 2.0.0).
|
||||
let frame: Frame;
|
||||
let navParam;
|
||||
if (frameId >= 0) {
|
||||
rootView = getFrameById(frameId);
|
||||
}
|
||||
else if (!rootView) {
|
||||
navParam = application.mainEntry;
|
||||
if (!navParam) {
|
||||
navParam = application.mainModule;
|
||||
}
|
||||
|
||||
if (navParam) {
|
||||
frame = new Frame();
|
||||
} else {
|
||||
// TODO: Throw an exception?
|
||||
throw new Error("A Frame must be used to navigate to a Page.");
|
||||
}
|
||||
|
||||
rootView = frame;
|
||||
}
|
||||
|
||||
// If there is savedInstanceState this call will recreate all fragments that were previously in the navigation.
|
||||
// We take care of associating them with a Page from our backstack in the onAttachFragment callback.
|
||||
// If there is savedInstanceState and activityInitialized is false we are restarted but process was killed.
|
||||
// For now we treat it like first run (e.g. we are not passing savedInstanceState so no fragments are being restored).
|
||||
// When we add support for application save/load state - revise this logic.
|
||||
var isRestart = !!savedInstanceState && activityInitialized;
|
||||
super.onCreate(isRestart ? savedInstanceState : null);
|
||||
|
||||
this[ROOT_VIEW] = rootView;
|
||||
|
||||
// Initialize native visual tree;
|
||||
rootView._onAttached(this);
|
||||
this.setContentView(rootView._nativeView, new org.nativescript.widgets.CommonLayoutParams());
|
||||
// frameId is negative w
|
||||
if (frame) {
|
||||
frame.navigate(navParam);
|
||||
}
|
||||
|
||||
activityInitialized = true;
|
||||
}
|
||||
|
||||
protected onSaveInstanceState(outState: android.os.Bundle): void {
|
||||
super.onSaveInstanceState(outState);
|
||||
let view = this.rootView;
|
||||
if (view instanceof Frame) {
|
||||
outState.putInt(INTENT_EXTRA, view.android.frameId);
|
||||
}
|
||||
}
|
||||
|
||||
protected onStart(): void {
|
||||
super.onStart();
|
||||
trace.write("NativeScriptActivity.onStart();", trace.categories.NativeLifecycle);
|
||||
let rootView = this.rootView
|
||||
if (rootView && !rootView.isLoaded) {
|
||||
rootView.onLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
protected onStop(): void {
|
||||
super.onStop();
|
||||
trace.write("NativeScriptActivity.onStop();", trace.categories.NativeLifecycle);
|
||||
let rootView = this.rootView
|
||||
if (rootView && rootView.isLoaded) {
|
||||
rootView.onUnloaded();
|
||||
}
|
||||
}
|
||||
|
||||
protected onDestroy(): void {
|
||||
let rootView = this.rootView
|
||||
if (rootView && rootView._context) {
|
||||
rootView._onDetached(true);
|
||||
}
|
||||
|
||||
super.onDestroy();
|
||||
trace.write("NativeScriptActivity.onDestroy();", trace.categories.NativeLifecycle);
|
||||
}
|
||||
|
||||
public onBackPressed(): void {
|
||||
trace.write("NativeScriptActivity.onBackPressed;", trace.categories.NativeLifecycle);
|
||||
|
||||
var args = <application.AndroidActivityBackPressedEventData>{
|
||||
eventName: "activityBackPressed",
|
||||
object: application.android,
|
||||
activity: this,
|
||||
cancel: false,
|
||||
};
|
||||
application.android.notify(args);
|
||||
|
||||
if (args.cancel) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!frameCommon.goBack()) {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
protected onActivityResult(requestCode: number, resultCode: number, data: android.content.Intent): void {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
trace.write(`NativeScriptActivity.onActivityResult(${requestCode}, ${resultCode}, ${data})`, trace.categories.NativeLifecycle);
|
||||
|
||||
var result = application.android.onActivityResult;
|
||||
if (result) {
|
||||
result(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
application.android.notify(<application.AndroidActivityResultEventData>{
|
||||
eventName: "activityResult",
|
||||
object: application.android,
|
||||
activity: this,
|
||||
requestCode: requestCode,
|
||||
resultCode: resultCode,
|
||||
intent: data
|
||||
});
|
||||
}
|
||||
}
|
1
ui/frame/frame.d.ts
vendored
1
ui/frame/frame.d.ts
vendored
@ -310,6 +310,5 @@ declare module "ui/frame" {
|
||||
//@private
|
||||
function reloadPage(): void;
|
||||
function resolvePageFromEntry(entry: NavigationEntry): pages.Page;
|
||||
function getActivity(): Object;
|
||||
//@endprivate
|
||||
}
|
Reference in New Issue
Block a user