Skip to content

Added @profile on several key methods in the Android lifecycle, refactored by extracting into methods a little #4685

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 30 additions & 19 deletions tns-core-modules/application/application.android.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,34 +180,45 @@ global.__onLiveSync = function () {
};

function initLifecycleCallbacks() {
// TODO: Verify whether the logic for triggerring application-wide events based on Activity callbacks is working properly
const setThemeOnLaunch = profile("setThemeOnLaunch", (activity: android.app.Activity) => {
// Set app theme after launch screen was used during startup
const activityInfo = activity.getPackageManager().getActivityInfo(activity.getComponentName(), android.content.pm.PackageManager.GET_META_DATA);
if (activityInfo.metaData) {
const setThemeOnLaunch = activityInfo.metaData.getInt("SET_THEME_ON_LAUNCH", -1);
if (setThemeOnLaunch !== -1) {
activity.setTheme(setThemeOnLaunch);
}
}
});

const notifyActivityCreated = profile("notifyActivityCreated", function(activity: android.app.Activity, savedInstanceState: android.os.Bundle) {
androidApp.notify(<AndroidActivityBundleEventData>{ eventName: ActivityCreated, object: androidApp, activity, bundle: savedInstanceState });
});

const subscribeForGlobalLayout = profile("subscribeForGlobalLayout", function(activity: android.app.Activity) {
const rootView = activity.getWindow().getDecorView().getRootView();
let onGlobalLayoutListener = new android.view.ViewTreeObserver.OnGlobalLayoutListener({
onGlobalLayout() {
notify({ eventName: displayedEvent, object: androidApp, activity });
let viewTreeObserver = rootView.getViewTreeObserver();
viewTreeObserver.removeOnGlobalLayoutListener(onGlobalLayoutListener);
}
});
rootView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
});

const lifecycleCallbacks = new android.app.Application.ActivityLifecycleCallbacks({
onActivityCreated: profile("onActivityCreated", function (activity: android.app.Activity, savedInstanceState: android.os.Bundle) {
// Set app theme after launch screen was used during startup
const activityInfo = activity.getPackageManager().getActivityInfo(activity.getComponentName(), android.content.pm.PackageManager.GET_META_DATA);
if (activityInfo.metaData) {
const setThemeOnLaunch = activityInfo.metaData.getInt("SET_THEME_ON_LAUNCH", -1);
if (setThemeOnLaunch !== -1) {
activity.setTheme(setThemeOnLaunch);
}
}
setThemeOnLaunch(activity);

if (!androidApp.startActivity) {
androidApp.startActivity = activity;
}

androidApp.notify(<AndroidActivityBundleEventData>{ eventName: ActivityCreated, object: androidApp, activity, bundle: savedInstanceState });
notifyActivityCreated(activity, savedInstanceState);

if (hasListeners(displayedEvent)) {
const rootView = activity.getWindow().getDecorView().getRootView();
let onGlobalLayoutListener = new android.view.ViewTreeObserver.OnGlobalLayoutListener({
onGlobalLayout() {
notify({ eventName: displayedEvent, object: androidApp, activity });
let viewTreeObserver = rootView.getViewTreeObserver();
viewTreeObserver.removeOnGlobalLayoutListener(onGlobalLayoutListener);
}
});
rootView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
subscribeForGlobalLayout(activity);
}
}),

Expand Down
5 changes: 4 additions & 1 deletion tns-core-modules/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@
"snapshot": {
"android": {
"tns-java-classes": {
"modules": ["ui/frame/activity", "ui/frame/fragment"]
"modules": [
"ui/frame/activity",
"ui/frame/fragment"
]
}
}
}
Expand Down
44 changes: 24 additions & 20 deletions tns-core-modules/ui/builder/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { isString, isDefined } from "../../utils/types";
import { ComponentModule, setPropertyValue, getComponentModule } from "./component-builder";
import { platformNames, device } from "../../platform";
import { resolveFileName } from "../../file-system/file-name-resolver";
import { profile } from "tns-core-modules/profiling";
import * as traceModule from "../../trace";

const ios = platformNames.ios.toLowerCase();
Expand Down Expand Up @@ -445,28 +446,28 @@ namespace xml2ui {
this._state = TemplateParser.State.FINISHED;

if (this._setTemplateProperty && this._templateProperty.name in this._templateProperty.parent.component) {
let template = this._build();
let template = this.buildTemplate();
this._templateProperty.parent.component[this._templateProperty.name] = template;
}
}
}

public _build(): Template {
public buildTemplate(): Template {
var context = this._context;
var errorFormat = this._templateProperty.errorFormat;
var sourceTracker = this._templateProperty.sourceTracker;
var template: Template = () => {
var template: Template = profile("Template()", () => {
var start: xml2ui.XmlArgsReplay;
var ui: xml2ui.ComponentParser;

(start = new xml2ui.XmlArgsReplay(this._recordedXmlStream, errorFormat))
// No platform filter, it has been filtered allready
// No platform filter, it has been filtered already
.pipe(new XmlStateParser(ui = new ComponentParser(context, errorFormat, sourceTracker)));

start.replay();

return ui.rootComponentModule.component;
}
});
return template;
}
}
Expand All @@ -492,7 +493,7 @@ namespace xml2ui {
for (let i = 0; i < this._childParsers.length; i++) {
templates.push({
key: this._childParsers[i]["key"],
createView: this._childParsers[i]._build()
createView: this._childParsers[i].buildTemplate()
});
}
this.templateProperty.parent.component[this.templateProperty.name] = templates;
Expand Down Expand Up @@ -535,6 +536,22 @@ namespace xml2ui {
this.sourceTracker = sourceTracker;
}

@profile
private buildComponent(args: xml.ParserEvent): ComponentModule {
if (args.prefix && args.namespace) {
// Custom components
return loadCustomComponent(args.namespace, args.elementName, args.attributes, this.context, this.currentRootView);
} else {
// Default components
let namespace = args.namespace;
if (defaultNameSpaceMatcher.test(namespace || '')) {
//Ignore the default ...tns.xsd namespace URL
namespace = undefined;
}
return getComponentModule(args.elementName, namespace, args.attributes, this.context, this.moduleNamePath);
}
}

public parse(args: xml.ParserEvent): XmlStateConsumer {

// Get the current parent.
Expand Down Expand Up @@ -579,20 +596,7 @@ namespace xml2ui {

} else {

var componentModule: ComponentModule;

if (args.prefix && args.namespace) {
// Custom components
componentModule = loadCustomComponent(args.namespace, args.elementName, args.attributes, this.context, this.currentRootView);
} else {
// Default components
let namespace = args.namespace;
if (defaultNameSpaceMatcher.test(namespace || '')) {
//Ignore the default ...tns.xsd namespace URL
namespace = undefined;
}
componentModule = getComponentModule(args.elementName, namespace, args.attributes, this.context, this.moduleNamePath);
}
var componentModule = this.buildComponent(args);

if (componentModule) {
this.sourceTracker(componentModule.component, args.position);
Expand Down
91 changes: 54 additions & 37 deletions tns-core-modules/ui/builder/component-builder/component-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { isEventOrGesture } from "../../core/bindable";
import { File, path, knownFolders } from "../../../file-system";
import { getBindingOptions, bindingConstants } from "../binding-builder";
import { resolveFileName } from "../../../file-system/file-name-resolver";
import { profile } from "tns-core-modules/profiling";
import * as debugModule from "../../../utils/debug";
import * as platform from "../../../platform";

Expand All @@ -24,14 +25,9 @@ const CODEFILE = "codeFile";
const CSSFILE = "cssFile";
const IMPORT = "import";

export function getComponentModule(elementName: string, namespace: string, attributes: Object, exports: Object, moduleNamePath?: string): ComponentModule {
const createComponentInstance = profile("createComponentInstance", (elementName: string, namespace: string): { instance: View, instanceModule: Object } => {
var instance: View;
var instanceModule: Object;
var componentModule: ComponentModule;

// Support lower-case-dashed component declaration in the XML (https://github.com/NativeScript/NativeScript/issues/309).
elementName = elementName.split("-").map(s => { return s[0].toUpperCase() + s.substring(1) }).join("");

// Get module id.
var moduleId = MODULES[elementName] || UI_PATH +
(elementName.toLowerCase().indexOf("layout") !== -1 ? "layouts/" : "") +
Expand Down Expand Up @@ -70,7 +66,10 @@ export function getComponentModule(elementName: string, namespace: string, attri
throw new debug.ScopeError(ex, "Module '" + moduleId + "' not found for element '" + (namespace ? namespace + ":" : "") + elementName + "'.");
}

let cssApplied = false;
return { instance, instanceModule };
});

const getComponentModuleExports = profile("getComponentModuleExports", (instance: View, moduleExports: Object, attributes: Object): Object => {
if (attributes) {
if (attributes[IMPORT]) {
let importPath = attributes[IMPORT].trim();
Expand All @@ -79,39 +78,43 @@ export function getComponentModule(elementName: string, namespace: string, attri
importPath = path.join(knownFolders.currentApp().path, importPath.replace("~/", ""));
}

exports = global.loadModule(importPath);
(<any>instance).exports = exports;
moduleExports = global.loadModule(importPath);
(<any>instance).exports = moduleExports;
}

// if (instance instanceof Page) {
if (attributes[CODEFILE]) {
let codeFilePath = attributes[CODEFILE].trim();
if (codeFilePath.indexOf("~/") === 0) {
codeFilePath = path.join(knownFolders.currentApp().path, codeFilePath.replace("~/", ""));
}
if (attributes[CODEFILE]) {
let codeFilePath = attributes[CODEFILE].trim();
if (codeFilePath.indexOf("~/") === 0) {
codeFilePath = path.join(knownFolders.currentApp().path, codeFilePath.replace("~/", ""));
}

const codeFilePathWithExt = codeFilePath.indexOf(".js") !== -1 ? codeFilePath : `${codeFilePath}.js`;
if (File.exists(codeFilePathWithExt)) {
exports = global.loadModule(codeFilePath);
(<any>instance).exports = exports;
} else {
throw new Error(`Code file with path "${codeFilePathWithExt}" cannot be found!`);
}
const codeFilePathWithExt = codeFilePath.indexOf(".js") !== -1 ? codeFilePath : `${codeFilePath}.js`;
if (File.exists(codeFilePathWithExt)) {
moduleExports = global.loadModule(codeFilePath);
(<any>instance).exports = moduleExports;
} else {
throw new Error(`Code file with path "${codeFilePathWithExt}" cannot be found!`);
}
}
}
return moduleExports;
});

if (attributes[CSSFILE] && typeof (<any>instance).addCssFile === "function") {
let cssFilePath = attributes[CSSFILE].trim();
if (cssFilePath.indexOf("~/") === 0) {
cssFilePath = path.join(knownFolders.currentApp().path, cssFilePath.replace("~/", ""));
}
if (File.exists(cssFilePath)) {
(<any>instance).addCssFile(cssFilePath);
cssApplied = true;
} else {
throw new Error(`Css file with path "${cssFilePath}" cannot be found!`);
}
const applyComponentCss = profile("applyComponentCss", (instance: View, moduleNamePath: string, attributes: Object) => {
let cssApplied = false;
if (attributes) {
if (attributes[CSSFILE] && typeof (<any>instance).addCssFile === "function") {
let cssFilePath = attributes[CSSFILE].trim();
if (cssFilePath.indexOf("~/") === 0) {
cssFilePath = path.join(knownFolders.currentApp().path, cssFilePath.replace("~/", ""));
}
if (File.exists(cssFilePath)) {
(<any>instance).addCssFile(cssFilePath);
cssApplied = true;
} else {
throw new Error(`Css file with path "${cssFilePath}" cannot be found!`);
}
// }
}
}

if (typeof (<any>instance).addCssFile === "function") {//instance instanceof Page) {
Expand All @@ -129,7 +132,9 @@ export function getComponentModule(elementName: string, namespace: string, attri
(<any>instance)._refreshCss();
}
}
});

const applyComponentAttributes = profile("applyComponentAttributes", (instance: View, instanceModule: Object, moduleExports: Object, attributes: Object) => {
if (instance && instanceModule) {
for (let attr in attributes) {

Expand Down Expand Up @@ -157,16 +162,28 @@ export function getComponentModule(elementName: string, namespace: string, attri
}

if (subObj !== undefined && subObj !== null) {
setPropertyValue(subObj, instanceModule, exports, subPropName, attrValue);
setPropertyValue(subObj, instanceModule, moduleExports, subPropName, attrValue);
}
} else {
setPropertyValue(instance, instanceModule, exports, attr, attrValue);
setPropertyValue(instance, instanceModule, moduleExports, attr, attrValue);
}
}
}
});

export function getComponentModule(elementName: string, namespace: string, attributes: Object, moduleExports: Object, moduleNamePath?: string): ComponentModule {
// Support lower-case-dashed component declaration in the XML (https://github.com/NativeScript/NativeScript/issues/309).
elementName = elementName.split("-").map(s => { return s[0].toUpperCase() + s.substring(1) }).join("");

const { instance, instanceModule } = createComponentInstance(elementName, namespace);
moduleExports = getComponentModuleExports(instance, moduleExports, attributes);
applyComponentCss(instance, moduleNamePath, attributes);
applyComponentAttributes(instance, instanceModule, moduleExports, attributes);

var componentModule;
if (instance && instanceModule) {
componentModule = { component: instance, exports: instanceModule };
}

return componentModule;
}

Expand Down
Loading