mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-17 21:01:34 +08:00
Merge pull request #2244 from NativeScript/atanasovg/remove-app-activity-extends
Remove the android.app.Application extend from the core modules
This commit is contained in:
@ -7,40 +7,9 @@ import * as typesModule from "utils/types";
|
|||||||
global.moduleMerge(appModule, exports);
|
global.moduleMerge(appModule, exports);
|
||||||
var typedExports: typeof definition = exports;
|
var typedExports: typeof definition = exports;
|
||||||
|
|
||||||
@JavaProxy("com.tns.NativeScriptApplication")
|
function initLifecycleCallbacks() {
|
||||||
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"
|
|
||||||
|
|
||||||
function initEvents() {
|
|
||||||
// TODO: Verify whether the logic for triggerring application-wide events based on Activity callbacks is working properly
|
// TODO: Verify whether the logic for triggerring application-wide events based on Activity callbacks is working properly
|
||||||
var lifecycleCallbacks = new android.app.Application.ActivityLifecycleCallbacks({
|
let lifecycleCallbacks = new android.app.Application.ActivityLifecycleCallbacks({
|
||||||
onActivityCreated: function (activity: any, bundle: any) {
|
onActivityCreated: function (activity: any, bundle: any) {
|
||||||
if (!androidApp.startActivity) {
|
if (!androidApp.startActivity) {
|
||||||
androidApp.startActivity = activity;
|
androidApp.startActivity = activity;
|
||||||
@ -55,7 +24,6 @@ function initEvents() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onActivityDestroyed: function (activity: any) {
|
onActivityDestroyed: function (activity: any) {
|
||||||
|
|
||||||
// Clear the current activity reference to prevent leak
|
// Clear the current activity reference to prevent leak
|
||||||
if (activity === androidApp.foregroundActivity) {
|
if (activity === androidApp.foregroundActivity) {
|
||||||
androidApp.foregroundActivity = undefined;
|
androidApp.foregroundActivity = undefined;
|
||||||
@ -150,6 +118,54 @@ function initEvents() {
|
|||||||
return lifecycleCallbacks;
|
return lifecycleCallbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let currentOrientation: number;
|
||||||
|
function initComponentCallbacks() {
|
||||||
|
let componentCallbacks = new android.content.ComponentCallbacks2({
|
||||||
|
onLowMemory: function() {
|
||||||
|
gc();
|
||||||
|
java.lang.System.gc();
|
||||||
|
typedExports.notify(<definition.ApplicationEventData>{ eventName: typedExports.lowMemoryEvent, object: this, android: this });
|
||||||
|
},
|
||||||
|
|
||||||
|
onTrimMemory: function(level: number) {
|
||||||
|
// TODO: This is skipped for now, test carefully for OutOfMemory exceptions
|
||||||
|
},
|
||||||
|
|
||||||
|
onConfigurationChanged: function(newConfig: android.content.res.Configuration) {
|
||||||
|
let newOrientation = newConfig.orientation;
|
||||||
|
if(newOrientation === currentOrientation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentOrientation = newOrientation;
|
||||||
|
|
||||||
|
let enums = require("ui/enums");
|
||||||
|
let newValue;
|
||||||
|
|
||||||
|
switch (orientation) {
|
||||||
|
case android.content.res.Configuration.ORIENTATION_LANDSCAPE:
|
||||||
|
newValue = enums.DeviceOrientation.landscape;
|
||||||
|
break;
|
||||||
|
case android.content.res.Configuration.ORIENTATION_PORTRAIT:
|
||||||
|
newValue = enums.DeviceOrientation.portrait;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
newValue = enums.DeviceOrientation.unknown;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedExports.notify(<definition.OrientationChangedEventData>{
|
||||||
|
eventName: typedExports.orientationChangedEvent,
|
||||||
|
android: androidApp.nativeApp,
|
||||||
|
newValue: newValue,
|
||||||
|
object: typedExports.android,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return componentCallbacks;
|
||||||
|
}
|
||||||
|
|
||||||
export class AndroidApplication extends observable.Observable implements definition.AndroidApplication {
|
export class AndroidApplication extends observable.Observable implements definition.AndroidApplication {
|
||||||
public static activityCreatedEvent = "activityCreated";
|
public static activityCreatedEvent = "activityCreated";
|
||||||
public static activityDestroyedEvent = "activityDestroyed";
|
public static activityDestroyedEvent = "activityDestroyed";
|
||||||
@ -187,15 +203,20 @@ export class AndroidApplication extends observable.Observable implements definit
|
|||||||
|
|
||||||
public onActivityResult: (requestCode: number, resultCode: number, data: android.content.Intent) => void;
|
public onActivityResult: (requestCode: number, resultCode: number, data: android.content.Intent) => void;
|
||||||
|
|
||||||
private _eventsToken: any;
|
|
||||||
|
|
||||||
public init(nativeApp: any) {
|
public init(nativeApp: any) {
|
||||||
|
if(this.nativeApp) {
|
||||||
|
throw new Error("application.android already initialized.")
|
||||||
|
}
|
||||||
|
|
||||||
this.nativeApp = nativeApp;
|
this.nativeApp = nativeApp;
|
||||||
this.packageName = nativeApp.getPackageName();
|
this.packageName = nativeApp.getPackageName();
|
||||||
this.context = nativeApp.getApplicationContext();
|
this.context = nativeApp.getApplicationContext();
|
||||||
|
|
||||||
this._eventsToken = initEvents();
|
let lifecycleCallbacks = initLifecycleCallbacks();
|
||||||
this.nativeApp.registerActivityLifecycleCallbacks(this._eventsToken);
|
let componentCallbacks = initComponentCallbacks();
|
||||||
|
this.nativeApp.registerActivityLifecycleCallbacks(lifecycleCallbacks);
|
||||||
|
this.nativeApp.registerComponentCallbacks(componentCallbacks);
|
||||||
|
|
||||||
this._registerPendingReceivers();
|
this._registerPendingReceivers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,11 +261,11 @@ export class AndroidApplication extends observable.Observable implements definit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var androidApp = new AndroidApplication();
|
let androidApp = new AndroidApplication();
|
||||||
// use the exports object instead of 'export var' due to global namespace collision
|
// use the exports object instead of 'export var' due to global namespace collision
|
||||||
typedExports.android = androidApp;
|
typedExports.android = androidApp;
|
||||||
|
|
||||||
var BroadcastReceiverClass;
|
let BroadcastReceiverClass;
|
||||||
function ensureBroadCastReceiverClass() {
|
function ensureBroadCastReceiverClass() {
|
||||||
if (BroadcastReceiverClass) {
|
if (BroadcastReceiverClass) {
|
||||||
return;
|
return;
|
||||||
@ -269,12 +290,19 @@ function ensureBroadCastReceiverClass() {
|
|||||||
BroadcastReceiverClass = BroadcastReceiver;
|
BroadcastReceiverClass = BroadcastReceiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
var started = false;
|
let started = false;
|
||||||
export function start(entry?: frame.NavigationEntry) {
|
export function start(entry?: frame.NavigationEntry) {
|
||||||
if (started) {
|
if (started) {
|
||||||
throw new Error("Application is already started.");
|
throw new Error("Application is already started.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!androidApp.nativeApp) {
|
||||||
|
// we are still not initialized, this is possible if no 'androidApp.init' call has been made
|
||||||
|
let utils = require("utils/utils");
|
||||||
|
let nativeApp = utils.ad.getApplication();
|
||||||
|
androidApp.init(nativeApp);
|
||||||
|
}
|
||||||
|
|
||||||
started = true;
|
started = true;
|
||||||
if (entry) {
|
if (entry) {
|
||||||
typedExports.mainEntry = entry;
|
typedExports.mainEntry = entry;
|
||||||
@ -283,42 +311,6 @@ export function start(entry?: frame.NavigationEntry) {
|
|||||||
loadCss();
|
loadCss();
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentOrientation: number;
|
|
||||||
function setupOrientationListener(androidApp: AndroidApplication) {
|
|
||||||
androidApp.registerBroadcastReceiver(android.content.Intent.ACTION_CONFIGURATION_CHANGED, onConfigurationChanged);
|
|
||||||
currentOrientation = androidApp.context.getResources().getConfiguration().orientation;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onConfigurationChanged(context: android.content.Context, intent: android.content.Intent) {
|
|
||||||
var orientation = context.getResources().getConfiguration().orientation;
|
|
||||||
|
|
||||||
if (currentOrientation !== orientation) {
|
|
||||||
currentOrientation = orientation;
|
|
||||||
|
|
||||||
var enums = require("ui/enums");
|
|
||||||
|
|
||||||
var newValue;
|
|
||||||
switch (orientation) {
|
|
||||||
case android.content.res.Configuration.ORIENTATION_LANDSCAPE:
|
|
||||||
newValue = enums.DeviceOrientation.landscape;
|
|
||||||
break;
|
|
||||||
case android.content.res.Configuration.ORIENTATION_PORTRAIT:
|
|
||||||
newValue = enums.DeviceOrientation.portrait;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
newValue = enums.DeviceOrientation.unknown;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedExports.notify(<definition.OrientationChangedEventData>{
|
|
||||||
eventName: typedExports.orientationChangedEvent,
|
|
||||||
android: context,
|
|
||||||
newValue: newValue,
|
|
||||||
object: typedExports.android,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadCss() {
|
function loadCss() {
|
||||||
//HACK: identical to application.ios.ts
|
//HACK: identical to application.ios.ts
|
||||||
typedExports.appSelectors = typedExports.loadCss(typedExports.cssFile) || [];
|
typedExports.appSelectors = typedExports.loadCss(typedExports.cssFile) || [];
|
||||||
|
@ -377,6 +377,13 @@ declare module "application" {
|
|||||||
*/
|
*/
|
||||||
paused: boolean;
|
paused: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialized the android-specific application object with the native android.app.Application instance.
|
||||||
|
* This is useful when creating custom application types.
|
||||||
|
* @param nativeApp - the android.app.Application instance that started the app.
|
||||||
|
*/
|
||||||
|
init: (nativeApp) => void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Deprecated. Please use the respective event instead.] Direct handler of the [onActivityCreated method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
|
* [Deprecated. Please use the respective event instead.] Direct handler of the [onActivityCreated method](http://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html).
|
||||||
*/
|
*/
|
||||||
|
@ -148,10 +148,45 @@ export module ad {
|
|||||||
view.setEllipsize(value === enums.WhiteSpace.nowrap ? android.text.TextUtils.TruncateAt.END : null);
|
view.setEllipsize(value === enums.WhiteSpace.nowrap ? android.text.TextUtils.TruncateAt.END : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let nativeApp: android.app.Application;
|
||||||
|
declare var com;
|
||||||
export function getApplication() {
|
export function getApplication() {
|
||||||
return <android.app.Application>(<any>com.tns).NativeScriptApplication.getInstance();
|
if(!nativeApp) {
|
||||||
|
// check whether the com.tns.NativeScriptApplication type exists
|
||||||
|
if(com.tns.NativeScriptApplication) {
|
||||||
|
nativeApp = com.tns.NativeScriptApplication.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
// the getInstance might return null if com.tns.NativeScriptApplication exists but is not the starting app type
|
||||||
|
if(!nativeApp) {
|
||||||
|
// check whether application.android.init has been explicitly called
|
||||||
|
let application = require("application");
|
||||||
|
nativeApp = application.android.nativeApp;
|
||||||
|
|
||||||
|
if(!nativeApp) {
|
||||||
|
// TODO: Should we handle the case when a custom application type is provided and the user has not explicitly initialized the application module?
|
||||||
|
let clazz = java.lang.Class.forName("android.app.ActivityThread");
|
||||||
|
if(clazz) {
|
||||||
|
let method = clazz.getMethod("currentApplication", null);
|
||||||
|
if(method) {
|
||||||
|
nativeApp = method.invoke(null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we cannot work without having the app instance
|
||||||
|
if(!nativeApp) {
|
||||||
|
throw new Error("Failed to retrieve native Android Application object. If you have a custom android.app.Application type implemented make sure that you've called the '<application-module>.android.init' method.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nativeApp;
|
||||||
|
}
|
||||||
|
export function getApplicationContext() {
|
||||||
|
let app = getApplication();
|
||||||
|
return app.getApplicationContext();
|
||||||
}
|
}
|
||||||
export function getApplicationContext() { return <android.content.Context>getApplication().getApplicationContext(); }
|
|
||||||
|
|
||||||
var inputMethodManager: android.view.inputmethod.InputMethodManager;
|
var inputMethodManager: android.view.inputmethod.InputMethodManager;
|
||||||
export function getInputMethodManager() {
|
export function getInputMethodManager() {
|
||||||
|
Reference in New Issue
Block a user