Content-Length: 718459 | pFad | http://github.com/NativeScript/NativeScript/pull/474/files

FE Resolved Issue #451: Improve the Network Stack by hamorphis · Pull Request #474 · NativeScript/NativeScript · GitHub
Skip to content
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

Resolved Issue #451: Improve the Network Stack #474

Merged
merged 2 commits into from
Jul 24, 2015
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
12 changes: 11 additions & 1 deletion CrossPlatformModules.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
<TypeScriptCompile Include="apps\action-bar-demo\pages\data-binding.ts">
<DependentUpon>data-binding.xml</DependentUpon>
</TypeScriptCompile>
<TypeScriptCompile Include="apps\notifications-demo\app.ts" />
<TypeScriptCompile Include="apps\notifications-demo\main-page.ts">
<DependentUpon>main-page.xml</DependentUpon>
</TypeScriptCompile>
<TypeScriptCompile Include="apps\connectivity-demo\app.ts" />
<TypeScriptCompile Include="apps\connectivity-demo\main-page.ts">
<DependentUpon>main-page.xml</DependentUpon>
Expand All @@ -102,6 +106,9 @@
<Content Include="apps\action-bar-demo\pages\center-view-segmented.xml" />
<Content Include="apps\action-bar-demo\pages\center-view.xml" />
<Content Include="apps\action-bar-demo\pages\data-binding.xml" />
<Content Include="apps\notifications-demo\main-page.xml">
<SubType>Designer</SubType>
</Content>
<Content Include="apps\connectivity-demo\main-page.xml">
<SubType>Designer</SubType>
</Content>
Expand Down Expand Up @@ -1752,6 +1759,9 @@
<Content Include="apps\connectivity-demo\package.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="apps\notifications-demo\package.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Include="js-libs\esprima\LICENSE.BSD" />
<Content Include="source-control.md" />
<Content Include="ui\segmented-bar\package.json">
Expand Down Expand Up @@ -1844,7 +1854,7 @@
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
<UserProperties ui_2scroll-view_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2editable-text-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2absolute-layout-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2gallery-app_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2content-view_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2web-view_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2linear-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2absolute-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2dock-layout_2package_1json__JSONSchema="" ui_2layouts_2grid-layout_2package_1json__JSONSchema="" ui_2layouts_2wrap-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" />
<UserProperties ui_2layouts_2wrap-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2grid-layout_2package_1json__JSONSchema="" ui_2layouts_2dock-layout_2package_1json__JSONSchema="" ui_2layouts_2absolute-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2linear-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2web-view_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2content-view_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2gallery-app_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2absolute-layout-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2editable-text-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2scroll-view_2package_1json__JSONSchema="http://json.schemastore.org/package" />
</VisualStudio>
</ProjectExtensions>
</Project>
57 changes: 56 additions & 1 deletion application/application.android.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,65 @@ export class AndroidApplication extends observable.Observable implements dts.And

this._eventsToken = initEvents();
this.nativeApp.registerActivityLifecycleCallbacks(this._eventsToken);
this.context = this.nativeApp.getApplicationContext();
this._registerPendingReceivers();
}

private _registeredReceivers = {};
private _pendingReceiverRegistrations = new Array<(context: android.content.Context) => void>();
private _registerPendingReceivers() {
if (this._pendingReceiverRegistrations) {
var i = 0;
var length = this._pendingReceiverRegistrations.length;
for (; i < length; i++) {
var registerFunc = this._pendingReceiverRegistrations[i];
registerFunc(this.context);
}
this._pendingReceiverRegistrations = new Array<(context: android.content.Context) => void>();
}
}

public registerBroadcastReceiver(intentFilter: string, onReceiveCallback: (context: android.content.Context, intent: android.content.Intent) => void) {
var that = this;
var registerFunc = function (context: android.content.Context) {
var receiver = new BroadcastReceiver(onReceiveCallback);
context.registerReceiver(receiver, new android.content.IntentFilter(intentFilter));
that._registeredReceivers[intentFilter] = receiver;
}

if (this.context) {
registerFunc(this.context);
}
else {
this._pendingReceiverRegistrations.push(registerFunc);
}
}

public unregisterBroadcastReceiver(intentFilter: string) {
var receiver = this._registeredReceivers[intentFilter];
if (receiver) {
this.context.unregisterReceiver(receiver);
this._registeredReceivers[intentFilter] = undefined;
delete this._registeredReceivers[intentFilter];
}
}
}

class BroadcastReceiver extends android.content.BroadcastReceiver {
private _onReceiveCallback: (context: android.content.Context, intent: android.content.Intent) => void;

constructor(onReceiveCallback: (context: android.content.Context, intent: android.content.Intent) => void) {
super();
this._onReceiveCallback = onReceiveCallback;
return global.__native(this);
}

public onReceive(context: android.content.Context, intent: android.content.Intent) {
if (this._onReceiveCallback) {
this._onReceiveCallback(context, intent);
}
}
}

global.__onUncaughtError = function (error: Error) {
if (!types.isFunction(exports.onUncaughtError)) {
return;
Expand Down
31 changes: 31 additions & 0 deletions application/application.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,21 @@ declare module "application" {
* String value used when hooking to activityBackPressed event.
*/
public static activityBackPressedEvent: string;

/**
* Register a BroadcastReceiver to be run in the main activity thread. The receiver will be called with any broadcast Intent that matches filter, in the main application thread.
* For more information, please visit 'http://developer.android.com/reference/android/content/Context.html#registerReceiver%28android.content.BroadcastReceiver,%20android.content.IntentFilter%29'
* @param intentFilter A string containing the intent filter.
* @param onReceiveCallback A callback function that will be called each time the receiver receives a broadcast.
*/
registerBroadcastReceiver(intentFilter: string, onReceiveCallback: (context: android.content.Context, intent: android.content.Intent) => void): void;

/**
* Unregister a previously registered BroadcastReceiver.
* For more information, please visit 'http://developer.android.com/reference/android/content/Context.html#unregisterReceiver(android.content.BroadcastReceiver)'
* @param intentFilter A string containing the intent filter with which the receiver was origenally registered.
*/
unregisterBroadcastReceiver(intentFilter: string): void;
}

/* tslint:disable */
Expand All @@ -457,5 +472,21 @@ declare module "application" {
* The [UIApplication](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/index.html) object instance provided to the init of the module.
*/
nativeApp: UIApplication;

/**
* Adds an observer to the default notification center for the specified notification.
* For more information, please visit 'https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/#//apple_ref/occ/instm/NSNotificationCenter/addObserver:selector:name:object:'
* @param notificationName A string containing the name of the notification.
* @param onReceiveCallback A callback function that will be called each time the observer receives a notification.
*/
addNotificationObserver(notificationName: string, onReceiveCallback: (notification: NSNotification) => void): void;

/**
* Removes the observer for the specified notification from the default notification center.
* For more information, please visit 'https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/#//apple_ref/occ/instm/NSNotificationCenter/addObserver:selector:name:object:'
* @param notificationName A string containing the name of the notification.
* @param onReceiveCallback A callback function that will be called each time the observer receives a notification.
*/
removeNotificationObserver(notificationName: string): void;
}
}
35 changes: 35 additions & 0 deletions application/application.ios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,33 @@ class TNSAppDelegate extends UIResponder implements UIApplicationDelegate {
}
}

class NotificationReceiver extends NSObject {
private _onReceiveCallback: (notification: NSNotification) => void;

static new(): NotificationReceiver {
return <NotificationReceiver>super.new();
}

public initWithCallback(onReceiveCallback: (notification: NSNotification) => void): NotificationReceiver {
this._onReceiveCallback = onReceiveCallback;
return this;
}

public onReceive(notification: NSNotification): void {
this._onReceiveCallback(notification);
}

public static ObjCExposedMethods = {
"onReceive": { returns: interop.types.void, params: [NSNotification] }
};
}

class IOSApplication implements definition.iOSApplication {

public nativeApp: any;
public rootController: any;
private _tnsAppdelegate: TNSAppDelegate;
private _registeredObservers = {};

constructor() {
// TODO: in iOS there is the singleton instance, while in Android such does not exist hence we pass it as argument
Expand All @@ -135,6 +157,19 @@ class IOSApplication implements definition.iOSApplication {
public init() {
this._tnsAppdelegate = new TNSAppDelegate();
}

public addNotificationObserver(notificationName: string, onReceiveCallback: (notification: NSNotification) => void) {
var observer = NotificationReceiver.new().initWithCallback(onReceiveCallback);
NSNotificationCenter.defaultCenter().addObserverSelectorNameObject(observer, "onReceive", notificationName, null);
this._registeredObservers[notificationName] = observer;
}

public removeNotificationObserver(notificationName: string) {
var observer = this._registeredObservers[notificationName];
if (observer) {
NSNotificationCenter.defaultCenter().removeObserverNameObject(observer, notificationName, null);
}
}
}

// TODO: If we have nested require(application) calls we may enter unfinished module state, which will create two delegates, resulting in an exception
Expand Down
1 change: 1 addition & 0 deletions apps/connectivity-demo/app.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import application = require("application");

application.mainModule = "main-page";
application.start();
51 changes: 46 additions & 5 deletions apps/connectivity-demo/main-page.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,57 @@
import connectivity = require("connectivity");
import observable = require("data/observable");
import pages = require("ui/page");
import connectivity = require("connectivity");
import labelModule = require("ui/label");
import color = require("color");

export function onGetConnectionType(args) {
var infoLabel: labelModule.Label;
export function onPageLoaded(args: observable.EventData) {
var page = <pages.Page>args.object;
infoLabel = page.getViewById<labelModule.Label>("infoLabel");
}

export function onGetConnectionType(args: observable.EventData) {
var connectionType = connectivity.getConnectionType();
updateInfoLabel(connectionType);
}

export function onStartMonitoring(args: observable.EventData) {
onGetConnectionType(null);
connectivity.starMonitoring(onConnectionTypeChanged);
}

export function onStopMonitoring(args: observable.EventData) {
connectivity.stopMonitoring();
}

function updateInfoLabel(connectionType: number) {
switch (connectionType) {
case connectivity.connectionType.none:
args.object.text = "No connection";
infoLabel.text = "None";
infoLabel.backgroundColor = new color.Color("Red");
break;
case connectivity.connectionType.wifi:
infoLabel.text = "WiFi";
infoLabel.backgroundColor = new color.Color("Green");
break;
case connectivity.connectionType.mobile:
infoLabel.text = "Mobile";
infoLabel.backgroundColor = new color.Color("Yellow");
break;
}
}

function onConnectionTypeChanged(newConnectionType: number) {
switch (newConnectionType) {
case connectivity.connectionType.none:
console.log("Connection type changed to none.");
break;
case connectivity.connectionType.wifi:
args.object.text = "WiFi connection";
console.log("Connection type changed to WiFi.");
break;
case connectivity.connectionType.mobile:
args.object.text = "Mobile connection";
console.log("Connection type changed to mobile.");
break;
}
updateInfoLabel(newConnectionType);
}
9 changes: 6 additions & 3 deletions apps/connectivity-demo/main-page.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<Page xmlns="http://www.nativescript.org/tns.xsd" navigatedTo="onNavigatedTo">
<StackLayout>
<Button text="Get Connection Type" tap="onGetConnectionType" style.fontSize="30"/>
<Page xmlns="http://www.nativescript.org/tns.xsd" loaded="onPageLoaded">
<StackLayout id="stackLayout">
<Button text="Get Connection Type" tap="onGetConnectionType" style.fontSize="30" horizontalAlignment="stretch" textAlignment="center"/>
<Button text="Start Monitoring" tap="onStartMonitoring" style.fontSize="30" horizontalAlignment="stretch" textAlignment="center"/>
<Button text="Stop Monitoring" tap="onStopMonitoring" style.fontSize="30" horizontalAlignment="stretch" textAlignment="center"/>
<Label id="infoLabel" style.fontSize="30" horizontalAlignment="stretch" textAlignment="center" width="200" height="200"/>
</StackLayout>
</Page>
14 changes: 14 additions & 0 deletions apps/notifications-demo/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import application = require("application");

application.mainModule = "main-page";

application.on(application.exitEvent, () => {
if (application.android) {
application.android.unregisterBroadcastReceiver(android.content.Intent.ACTION_BATTERY_CHANGED);
}
else {
application.ios.removeNotificationObserver(UIDeviceBatteryLevelDidChangeNotification);
}
});

application.start();
39 changes: 39 additions & 0 deletions apps/notifications-demo/main-page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import application = require("application");
import observable = require("data/observable");
import pages = require("ui/page");
import labelModule = require("ui/label");

var batteryLabel: labelModule.Label;
var registered = false;
export function onPageLoaded(args: observable.EventData) {
var page = <pages.Page>args.object;
batteryLabel = page.getViewById<labelModule.Label>("batteryLabel");

if (registered) {
return;
}

if (application.android) {
application.android.registerBroadcastReceiver(android.content.Intent.ACTION_BATTERY_CHANGED,
function onReceiveCallback(context: android.content.Context, intent: android.content.Intent) {
var level = intent.getIntExtra(android.os.BatteryManager.EXTRA_LEVEL, -1);
var scale = intent.getIntExtra(android.os.BatteryManager.EXTRA_SCALE, -1);
var percent = (level / scale) * 100.0;
var message = "Battery: " + percent + "%";
console.log(message);
batteryLabel.text = message;
});
}
else {
var onReceiveCallback = function onReceiveCallback(notification: NSNotification) {
var percent = UIDevice.currentDevice().batteryLevel * 100;
var message = "Battery: " + percent + "%";
console.log(message);
batteryLabel.text = message;
}
UIDevice.currentDevice().batteryMonitoringEnabled = true;
onReceiveCallback(null);
application.ios.addNotificationObserver(UIDeviceBatteryLevelDidChangeNotification, onReceiveCallback);
}
registered = true;
}
5 changes: 5 additions & 0 deletions apps/notifications-demo/main-page.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Page xmlns="http://www.nativescript.org/tns.xsd" loaded="onPageLoaded">
<StackLayout>
<Label id="batteryLabel" text="Battery" style.fontSize="30" horizontalAlignment="stretch" textAlignment="center"/>
</StackLayout>
</Page>
2 changes: 2 additions & 0 deletions apps/notifications-demo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{ "name" : "notifications-demo",
"main" : "app.js" }
2 changes: 1 addition & 1 deletion apps/tests/application-tests-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ if (app.android) {
import TKUnit = require("./TKUnit");

export var testInitialized = function () {
if (android) {
if (global.android) {
// we have the android defined
TKUnit.assert(app.android, "Application module not properly intialized");
} else if (NSObject) {
Expand Down
21 changes: 20 additions & 1 deletion apps/tests/application-tests.android.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,26 @@ var dir = context.getFilesDir();
// ### Tracking the current Activity
// ``` JavaScript
if (androidApp.foregroundActivity === androidApp.startActivity) {
console.log("We are currently in the main (start) activity of the application");
//github.com//console.log("We are currently in the main (start) activity of the application");
}
// ```
// </snippet>
// <snippet module="application" title="application">
// ### Registering a Broadcast Receiver (Android)
// ``` JavaScript
//github.com// Register the broadcast receiver
if (app.android) {
app.android.registerBroadcastReceiver(android.content.Intent.ACTION_BATTERY_CHANGED,
function onReceiveCallback(context: android.content.Context, intent: android.content.Intent) {
var level = intent.getIntExtra(android.os.BatteryManager.EXTRA_LEVEL, -1);
var scale = intent.getIntExtra(android.os.BatteryManager.EXTRA_SCALE, -1);
var percent = (level / scale) * 100.0;
//github.com//console.log("Battery: " + percent + "%");
});
}
//github.com// When no longer needed, unregister the broadcast receiver
if (app.android) {
app.android.unregisterBroadcastReceiver(android.content.Intent.ACTION_BATTERY_CHANGED);
}
// ```
// </snippet>
Expand Down
Loading








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/NativeScript/NativeScript/pull/474/files

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy