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);
|
||||
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"
|
||||
|
||||
function initEvents() {
|
||||
function initLifecycleCallbacks() {
|
||||
// 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) {
|
||||
if (!androidApp.startActivity) {
|
||||
androidApp.startActivity = activity;
|
||||
@ -55,7 +24,6 @@ function initEvents() {
|
||||
},
|
||||
|
||||
onActivityDestroyed: function (activity: any) {
|
||||
|
||||
// Clear the current activity reference to prevent leak
|
||||
if (activity === androidApp.foregroundActivity) {
|
||||
androidApp.foregroundActivity = undefined;
|
||||
@ -150,6 +118,54 @@ function initEvents() {
|
||||
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 {
|
||||
public static activityCreatedEvent = "activityCreated";
|
||||
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;
|
||||
|
||||
private _eventsToken: any;
|
||||
|
||||
public init(nativeApp: any) {
|
||||
if(this.nativeApp) {
|
||||
throw new Error("application.android already initialized.")
|
||||
}
|
||||
|
||||
this.nativeApp = nativeApp;
|
||||
this.packageName = nativeApp.getPackageName();
|
||||
this.context = nativeApp.getApplicationContext();
|
||||
|
||||
this._eventsToken = initEvents();
|
||||
this.nativeApp.registerActivityLifecycleCallbacks(this._eventsToken);
|
||||
let lifecycleCallbacks = initLifecycleCallbacks();
|
||||
let componentCallbacks = initComponentCallbacks();
|
||||
this.nativeApp.registerActivityLifecycleCallbacks(lifecycleCallbacks);
|
||||
this.nativeApp.registerComponentCallbacks(componentCallbacks);
|
||||
|
||||
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
|
||||
typedExports.android = androidApp;
|
||||
|
||||
var BroadcastReceiverClass;
|
||||
let BroadcastReceiverClass;
|
||||
function ensureBroadCastReceiverClass() {
|
||||
if (BroadcastReceiverClass) {
|
||||
return;
|
||||
@ -269,12 +290,19 @@ function ensureBroadCastReceiverClass() {
|
||||
BroadcastReceiverClass = BroadcastReceiver;
|
||||
}
|
||||
|
||||
var started = false;
|
||||
let started = false;
|
||||
export function start(entry?: frame.NavigationEntry) {
|
||||
if (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;
|
||||
if (entry) {
|
||||
typedExports.mainEntry = entry;
|
||||
@ -283,42 +311,6 @@ export function start(entry?: frame.NavigationEntry) {
|
||||
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() {
|
||||
//HACK: identical to application.ios.ts
|
||||
typedExports.appSelectors = typedExports.loadCss(typedExports.cssFile) || [];
|
||||
|
@ -377,6 +377,13 @@ declare module "application" {
|
||||
*/
|
||||
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).
|
||||
*/
|
||||
|
@ -148,10 +148,45 @@ export module ad {
|
||||
view.setEllipsize(value === enums.WhiteSpace.nowrap ? android.text.TextUtils.TruncateAt.END : null);
|
||||
}
|
||||
|
||||
let nativeApp: android.app.Application;
|
||||
declare var com;
|
||||
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;
|
||||
export function getInputMethodManager() {
|
||||
|
Reference in New Issue
Block a user