HTML5 App Web 3G (Moko365 Inc) 2012 04 07 ( ) www.miiceic.org.cn Copyright (C) 2009-2012 Moko365 Inc. All Rights Reserved. Copyright (C) 2010-2012 Moko365 Inc. All Rights Reserved. 3G HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. What’s PhoneGap? PhoneGap is a standards-based, open-source development framework for building cross-platform mobile apps with HTML, CSS and JavaScript for iPhone/iPad, Google Android, Palm, Symbian, BlackBerry, Windows Mobile and more. Write a PhoneGap app once with HTML and Javascript and deploy it to any mobile device without losing features of a native app. (--phonegap.com) HTML5 CSS3JavaScript (jQuery) HTML5 App HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Install PhoneGap http://phonegap.com/start Platform: iOS, Android, Blackberry, Windows Phone, WebOS, Symbian, (Bada), (Tizen) HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 1. Android SDK HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 2. New Android Project HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 3. ! libs ! assets/www HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 4. HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 5. cordova.jar Build Path -> Configure Build Path HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 6. package com.moko365.examples.phonegap; import android.app.Activity; import android.os.Bundle; import com.phonegap.*; import org.apache.cordova.*; public class HelloPhoneGapActivity extends ActivityDroidGap { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); super.loadUrl("file:///android_asset/www/index.html"); } } HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 7. AndroidManifest.xml HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 8. Activity HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 9. index.html HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. HTML5 App: PhoneGap

Hello World

HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. PhoneGap PhoneGap ! HTML/JavaScript Native API (Java) ! HTML/JavaScript Native API (Gap) ! Android WebView HTML/JavaScript ! PhoneGap WebView HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. jQuery PhoneGap

Hello World

HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. AJAX jQuery.ajax( url [, settings] ) success(data, textStatus, jqXHR) $.ajax({   url: "more.html",   cache: false,   success: function(html){     $("#results").append(html);   } }); HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. hello_ajax.html PhoneGap

Hello World

HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Web Page vs Web App HTML5 App ! jQuery assets/ CDN (Content-Deliver Network) ! App ! webkit Cache HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. “Expires” HTTP Header $ curl -I http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/ jquery.min.js HTTP/1.1 200 OK Vary: Accept-Encoding Content-Type: text/javascript; charset=UTF-8 Last-Modified: Wed, 23 Nov 2011 21:10:59 GMT Date: Tue, 06 Mar 2012 20:13:04 GMT Expires: Wed, 06 Mar 2013 20:13:04 GMT X-Content-Type-Options: nosniff Server: sffe X-XSS-Protection: 1; mode=block Cache-Control: public, max-age=31536000 Age: 42907 Transfer-Encoding: chunked HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. “Expires” $ curl -I http://cdn.moko365.com/ajax/libs/jquery/1.7.1/ jquery.min.js HTTP/1.1 200 OK Date: Wed, 07 Mar 2012 08:11:57 GMT Server: Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8e-fips- rhel5 mod_bwlimited/1.4 PHP/5.2.17 Last-Modified: Wed, 07 Mar 2012 08:11:06 GMT ETag: "1280544-16eac-4baa2b382ba80" Accept-Ranges: bytes Content-Length: 93868 Cache-Control: max-age=7257600 Expires: Wed, 30 May 2012 08:11:57 GMT Content-Type: application/javascript Copyright (C) 2010-2012 Moko365 Inc. All Rights Reserved. 3G HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. PhoneGap: 13 APIs http://docs.phonegap.com/en/1.5.0/ HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. PhoneGap APIs HTML JavaScript PhoneGap APIs PhoneGap APIs WebView Native APIs JavaScript HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Accelerometer API navigator.accelerometer.getCurrentAcceleration(accelerometerSuccess, accelerometerError); function onSuccess(acceleration) {     alert('Acceleration X: ' + acceleration.x + '\n' +           'Acceleration Y: ' + acceleration.y + '\n' +           'Acceleration Z: ' + acceleration.z + '\n' +           'Timestamp: '      + acceleration.timestamp + '\n'); }; function onError() {     alert('onError!'); }; navigator.accelerometer.getCurrentAcceleration(onSuccess, onError); HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. acceleration.html       Acceleration Example                

Example

   

getCurrentAcceleration

  HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. ViewPort       Acceleration Example                

Example

   

getCurrentAcceleration

  HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Camera API navigator.camera.getPicture( cameraSuccess, cameraError, [ cameraOptions ] ); navigator.camera.getPicture(onSuccess, onFail, { quality: 50 }); function onSuccess(imageData) {     var image = document.getElementById('myImage');     image.src = "data:image/jpeg;base64," + imageData; } function onFail(message) {     alert('Failed because: ' + message); } HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Compass API navigator.compass.getCurrentHeading(compassSuccess, compassError, compassOptions); function onSuccess(heading) {     alert('Heading: ' + heading.magneticHeading); }; function onError(error) {     alert('CompassError: ' error.code); }; navigator.compass.getCurrentHeading(onSuccess, onError); HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Connection API navigator.network.connection.type; function checkConnection() {     var networkState = navigator.network.connection.type;     var states = {};     states[Connection.UNKNOWN]  = 'Unknown connection';     states[Connection.ETHERNET] = 'Ethernet connection';     states[Connection.WIFI]     = 'WiFi connection';     states[Connection.CELL_2G]  = 'Cell 2G connection';     states[Connection.CELL_3G]  = 'Cell 3G connection';     states[Connection.CELL_4G]  = 'Cell 4G connection';     states[Connection.NONE]     = 'No network connection';     alert('Connection type: ' + states[networkState]); } checkConnection(); HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Media API var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]); media.getCurrentPosition(mediaSuccess, [mediaError]);     // Audio player     //     var my_media = new Media(src, onSuccess, onError);     // Update media position every second     var mediaTimer = setInterval(function() {         // get media position         my_media.getCurrentPosition(             // success callback             function(position) {                 if (position > -1) {                     console.log((position) + " sec");                 }             },             // error callback             function(e) {                 console.log("Error getting pos=" + e);             }         );     }, 1000); HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Storage API var db = window.openDatabase("test", "1.0", "Test DB", 1000000); function populateDB(tx) {      tx.executeSql('DROP TABLE IF EXISTS DEMO');      tx.executeSql('CREATE TABLE IF NOT EXISTS DEMO (id unique, data)');      tx.executeSql('INSERT INTO DEMO (id, data) VALUES (1, "First row")');      tx.executeSql('INSERT INTO DEMO (id, data) VALUES (2, "Second row")'); } function errorCB(err) {     alert("Error processing SQL: "+err.code); } function successCB() {     alert("success!"); } var db = window.openDatabase("Database", "1.0", "PhoneGap Demo", 200000); db.transaction(populateDB, errorCB, successCB); HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. HTML5 WebStorage PhoneGap HTML5 Web Storage (ofine) http://dev.w3.org/html5/webstorage/#the- localstorage-attribute HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Storage API var storage = window.localStorage;     // Wait for PhoneGap to load     //     document.addEventListener("deviceready", onDeviceReady, false);     // PhoneGap is ready     //     function onDeviceReady() {         window.localStorage.setItem("key", "value");         var keyname = window.localStorage.key(i);         // keyname is now equal to "key"         var value = window.localStorage.getItem("key");         // value is now equal to "value"         window.localStorage.removeItem("key");         window.localStorage.setItem("key2", "value2");         window.localStorage.clear();         // localStorage is now empty     } HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. cont... key(): Returns the name of the key at the position specified. getItem(): Returns the item identified by it's key. setItem(): Saves and item at the key provided. removeItem(): Removes the item identified by it's key. clear(): Removes all of the key value pairs. Copyright (C) 2010-2012 Moko365 Inc. All Rights Reserved. 3G HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 2 jQTouch jQuery Mobile ! http://jquerymobile.com/ ! http://jquerymobile.com/demos/1.0.1/ HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. “Coding” App UI “ ” App UI HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. CDN HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. PhoneGap + jQuery Mobile HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Mobile Page Structure Page Title ...content goes here... 2 1 viewport HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. “data-” attribute The jQuery Mobile framework uses HTML5 data- attributes to allow for markup-based initialization and configuration of widgets. These attributes are completely optional; calling plugins manually and passing options directly is also supported. See: http://jquerymobile.com/demos/1.1.0-rc.1/docs/api/data-attributes.html HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. data-role=”page” Page Title ...content goes here... “data-” attribute3 HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Page Title

Page Title

Page content goes here.

!!Open dialog!! !

Page Footer

HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Transition

Page Title

Page content goes here.

Open dialog

Page Footer

HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. jQuery jQuery Mobile CSS3 (theme) ThemeRoller Copyright (C) 2010-2012 Moko365 Inc. All Rights Reserved. 3G HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. JSON JSON (play /ˈdʒeɪsən/), or JavaScript Object Notation a lightweight text-based open standard designed for human-readable data interchange. It is derived from the JavaScript scripting language for representing simple data structures and associative arrays, called objects. Despite its relationship to JavaScript, it is language- independent, with parsers available for many languages. Source: http://en.wikipedia.org/wiki/JSON HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Basic Types Number (type not specified, but in practice double precision floating-point format, as this is how JavaScript in Web browsers treats it) String (double-quoted Unicode (UTF-8 by default), with backslash escaping) Boolean (true or false) Array (an ordered sequence of values, comma-separated and enclosed in square brackets; the values do not need to be of the same type) Object (an unordered collection of key:value pairs with the ':' character separating the key and the value, comma-separated and enclosed in curly braces; the keys must be strings and should be distinct from each other) null (empty) HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Schema [ 100, 500, 300, 200, 400 ] Array Array (an ordered sequence of values, comma- separated and enclosed in square brackets; the values do not need to be of the same type) HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Schema { height: 100, width: 500, } Single Row Object Object (an unordered collection of key:value pairs with the ':' character separating the key and the value, comma- separated and enclosed in curly braces; the keys must be strings and should be distinct from each other) HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Example 1 [ { color: "red", value: "#f00" }, { color: "green", value: "#0f0" }, { color: "blue", value: "#00f" }, { color: "cyan", value: "#0ff" } ] color red green blue cyan value #f00 #0f0 #00f #0ff HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Example 2 { "id": "0001", "type": "donut", "name": "Cake", "image": { "url": "images/0001.jpg", "width": 200, "height": 200 } } id type name image.url image.width image.height 1 donut Cake images/0001.jpg 200 200 HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Android App JSON org.json.*; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; [ { "name": “jollen”, "age": “30”, "address": “Unknown”}, { "name": “Paul”, "age": “30”, "address": “Unknown”}, { "name": “Peter”, "age": “30”, "address": “Unknown”} ] HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. private void parseJSON() { // Download JSON cache file String JSONCache = “simple.json”; try { mJsonArray = new JSONArray(JSONCache); } catch (JSONException e) { e.printStackTrace(); } for (int i = 0; i < mJsonArray.length(); i++) { try { JSONObject jsonObject = mJsonArray.getJSONObject(i); String url = jsonObject.getString("name"); String expires = jsonObject.getString("age"); String tags = jsonObject.getString("address"); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. JavaScript JSON json.js (json2.js) ! http://www.JSON.org/js.html Open source JSON parser for JavaScript HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Parsing Message using JSON in JavaScript Parsing Message using JSON in JavaScript HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Prefetching ! jQuery Mobile ! Implement your own Implement my own ! Prefetch lists: server JSON App HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Prefetching List [ { "url": "http://www.moko365.com/enterprise/news-20120306-appcan-launc", "expires": "2012-03-08" }, { "url": "http://www.moko365.com/enterprise/news-20120306-google-android-browser", "expires": "2012-03-08" }, { "url": "http://www.moko365.com/enterprise/ctimes-news-series-random-hacks-of-kindness-1", "expires": "2012-03-08" }, { "url": "http://www.moko365.com/enterprise/news-20120305-gartner%ef%bc%9aecosystem-is-the-key", "expires": "2012-03-08" }, . . . ] HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Javascript JSON Javascript JSON ! JSON jquery.tmpl.js JSON HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Table : Javascript+JSON HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. cont...
id image.width image.height image.url
HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Copyright (C) 2010-2012 Moko365 Inc. All Rights Reserved. 3G HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. PhoneGap (Override) WebView ( WebVIew) Activity (DroidGap) WebView JavaScriptInterface (Bind) JavaScript Java HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Custom WebView Override constructors of WebView XML Layout PhoneGap override loadUrl() JavaScriptInterface JavaScript-to-Java bindings HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 1. Override WebView public final class DroidWebView extends WebView { public MokoWebView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public MokoWebView(Context context, AttributeSet attrs) { super(context, attrs); } public MokoWebView(Context context) { super(context); } . . . } HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 2. Override Activity public final class DroidGap extends Activity { MyWebView mWebView; public loadUrl(String uri) { mWebView.loadUrl(uri); } . . . } HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Override Constructors override constructors XML Layout public final class DroidWebView extends WebView { MyWebView mWebView; public MokoWebView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public MokoWebView(Context context, AttributeSet attrs) { super(context, attrs); } } HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 3. XML Layout: res/layout/main.xml HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 4. public final class DroidGap extends Activity { DroidWebView mWebView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mAppView = (DroidWebView) findViewById(R.id.appView); this.loadUrl(“http://www.moko365.com”); } public loadUrl(String uri) { mWebView.loadUrl(uri); } . . . } HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 5. INTERNET         ... AndroidManifest.xml: HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. : Web App Source: Android Dev Guide. Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License. Figure 1. You can make your web content available to users in two ways: in a traditional web browser and in an Android application, by including a WebView in the layout. HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 6. WebChromeClient Override WebChromeClient public class MokoWebChromeClient extends WebChromeClient { } HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. cont... : JavaScript “Progress” /* This changes the setWebChromeClient to log alerts to LogCat! Important for Javascript Debugging */ mAppView.setWebChromeClient(new MokoWebChromeClient(this)); mAppView.getSettings().setJavaScriptEnabled(true); mAppView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); mAppView.setWebViewClient(new MokoWebViewClient(this)); HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. cont... public class MokoWebChromeClient extends WebChromeClient { @Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) { // TODO Auto-generated method stub return super.onJsAlert(view, url, message, result); } @Override public boolean onJsTimeout() { // TODO Auto-generated method stub return super.onJsTimeout(); } @Override public void onProgressChanged(WebView view, int newProgress) { // TODO Auto-generated method stub super.onProgressChanged(view, newProgress); } } HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 7. WebViewClient Override WebViewClient private class MyWebViewClient extends WebViewClient {     @Override     public boolean shouldOverrideUrlLoading(WebView view, String url) {         if (Uri.parse(url).getHost().equals("www.example.com")) {             // This is my web site, so do not override; let my WebView load the page             return false;         }         // Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs         Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));         startActivity(intent);         return true;     } } Source: Android Dev Guide. Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License. HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. cont... ( ): @Override public void onReceivedError (WebView view, int errorCode, String description, String failingUrl) { Log.i(TAG, "onReceivedError"); if (errorCode == ERROR_HOST_LOOKUP) { // Do something } else if (errorCode == ERROR_CONNECT) { // Do something } else if (errorCode == ERROR_FILE_NOT_FOUND) { // Do something } else if (errorCode == ERROR_UNSUPPORTED_SCHEME) { // Do something } else { // more... } } HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. cont... ( ): URL : WebView @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { Log.i(TAG, "shouldOverrideUrlLoading"); // load ‘url’ in ‘view’ view.loadUrl(url); return true; } Copyright (C) 2010-2012 Moko365 Inc. All Rights Reserved. 3G HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 1. JavaScript Android JavaScriptEngine /* This changes the setWebChromeClient to log alerts to LogCat! Important for Javascript Debugging */ mAppView.setWebChromeClient(new MokoWebChromeClient(this)); mAppView.getSettings().setJavaScriptEnabled(true); mAppView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); mAppView.setWebViewClient(new MokoWebViewClient(this)); HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 2. Binding Binding Android API public class MokoJavascriptInterface {     Context mContext;     /** Instantiate the interface and set the context */     MokoJavascriptInterface(Context c) {         mContext = c;     }     /** Show a toast from the web page */     public void showToast(String toast) {         Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();     } } HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 3. addJavascriptInterface() JavaScript DOM “moko” /* This changes the setWebChromeClient to log alerts to LogCat! Important for Javascript Debugging */ mAppView.setWebChromeClient(new MokoWebChromeClient(this)); mAppView.getSettings().setJavaScriptEnabled(true); mAppView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); mAppView.setWebViewClient(new MokoWebViewClient(this)); mAppView.addJavascriptInterface(new MokoJavascriptInterface(this), “moko”); HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. 4. Callback Java JavaScript “moko” Copyright (C) 2010-2012 Moko365 Inc. All Rights Reserved. 3G HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. ViewPort (View) (Port) (Content/Surface) HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. ViewPort Surface ViewPort Content (Surface) HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. ViewPort HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. ViewPort HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Content to View HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Scale = 2.0 scale=1.0 100% zoom 480x320 (Content) scale=2.0 200% zoom 960x640 (Content) HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Scale Scaling scale=1.0 (100% zoom) ! one CSS pixel one device pixel HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. ViewPort     Example     Source: Android Dev Guide. Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License. HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. ViewPort Size Figure 1. A web page with an image that's 320 pixels wide, in the Android Browser when there is no viewport metadata set (with "overview mode" enabled, the viewport is 800 pixels wide, by default). Source: Android Dev Guide. Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License. HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Automatic Sizing Figure 3. A web page with viewport width=device- width or initial-scale=1.0. Source: Android Dev Guide. Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License. (scale values 0.01 10) HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. ViewPort Scale “initial-scale” The initial scale of the page. The value is a float that indicates a multiplier for your web page size, relative to the screen size. For example, if you set the initial scale to "1.0" then the web page is displayed to match the resolution of the target density 1-to-1. If set to "2.0", then the page is enlarged (zoomed in) by a factor of 2. The default initial scale is calculated to fit the web page in the viewport size. Because the default viewport width is 800 pixels, if the device screen resolution is less than 800 pixels wide, the initial scale is something less than 1.0, by default, in order to fit the 800-pixel-wide page on the screen. Source: Android Dev Guide. Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License. HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. cont... “minimum-scale” The minimum scale to allow. The value is a float that indicates the minimum multiplier for your web page size, relative to the screen size. For example, if you set this to "1.0", then the page can't zoom out because the minimum size is 1-to-1 with the target density. “maximum-scale” The maximum scale to allow for the page. The value is a float that indicates the maximum multiplier for your web page size, relative to the screen size. For example, if you set this to "2.0", then the page can't zoom in more than 2 times the target size. “user-scalable” Whether the user can change the scale of the page at all (zoom in and out). Set to yes to allow scaling and no to disallow scaling. The default is yes. If you set this to no, then the minimum-scale and maximum-scale are ignored, because scaling is not possible. Source: Android Dev Guide. Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License. HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. ViewPort Target Density WebView density Figure 4. A web page with viewport width=device-width and target-densitydpi=device-dpi. Source: Android Dev Guide. Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License. HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. All Density Definition “device-dpi” Use the device's native dpi as the target dpi. Default scaling never occurs. “high-dpi” Use hdpi as the target dpi. Medium and low density screens scale down as appropriate. “medium-dpi” Use mdpi as the target dpi. High density screens scale up and low density screens scale down. This is the default target density. “low-dpi” Use ldpi as the target dpi. Medium and high density screens scale up as appropriate. - Specify a dpi value to use as the target dpi. Values must be within the range 70–400. Source: Android Dev Guide. Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License. HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. -webkit-device-pixel-ratio WebView “-webkit-device-pixel-ratio” CSS ! 0.75, 1.0, 1.5 Source: Android Dev Guide. Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License. HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. cont... #header { background:url(medium-density-image.png); } @media screen and (-webkit-device-pixel-ratio: 1.5) { /* CSS for high-density screens */ #header { background:url(high-density-image.png); } } @media screen and (-webkit-device-pixel-ratio: 0.75) { /* CSS for low-density screens */ #header { background:url(low-density-image.png); } Figure 5. A web page with CSS that's targetted to specific screen densities using the -webkit- device-pixel-ratio media feature. Notice that the hdpi device shows a different image that's applied in CSS. Source: Android Dev Guide. Portions of this page are reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License. HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Moko365 – Android HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. ViewPort width=device-width initial-scale=1.0 maximum-scale=1.0 user-scaleable=0 target-densitydpi=device-hdpi Copyright (C) 2010-2012 Moko365 Inc. All Rights Reserved. 3G HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. NodeJS Server-side JavaScript Google JavaScript V8 JavaScript I/O ! File access ! Database ! etc HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Node JS Thread Loop Event Loop with a Stack context switch overhead HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. index.html HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Nonblocking I/O HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. hello.js var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/html'}); res.end('

Hello World

\n'); }).listen(1234, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1234/'); HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. hello.js % node hello.js Server running at http://127.0.0.1:1234/ HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. NodeJS HTTP APIs var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/html'}); res.end('

Hello World

\n'); }).listen(1234, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1234/'); http.createServer([requestListener]) HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. requestListener var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/html'}); res.end('

Hello World

\n'); }).listen(1234, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1234/'); function (request, response) { } HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. HTTP Headers var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/html'}); res.end('

Hello World

\n'); }).listen(1234, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1234/'); { 'content-length': '123', 'content-type': 'text/plain', 'connection': 'keep-alive', 'accept': '*/*' } HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. HTTP Headers var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/html'}); res.end('

Hello World

\n'); }).listen(1234, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1234/'); server.listen(port, [hostname], [callback]) HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. NodeJS with JSON var options = { host: 'www.google.com', port: 80, path: '/upload', method: 'POST' }; var req = http.request(options, function(res) { console.log('STATUS: ' + res.statusCode); console.log('HEADERS: ' + JSON.stringify(res.headers)); res.setEncoding('utf8'); res.on('data', function (chunk) { console.log('BODY: ' + chunk); }); }); req.on('error', function(e) { console.log('problem with request: ' + e.message); }); // write data to request body req.write('data\n'); req.write('data\n'); req.end(); Source: http://nodejs.org/api/http.html HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Delete a File Write to the File HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Delete a File var fs = require('fs'); fs.unlink('/tmp/hello', function (err) { if (err) throw err; console.log('successfully deleted /tmp/hello'); }); HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Write to the File fs.writeFile('message.txt', 'Hello Node', function (err) { if (err) throw err; console.log('It\'s saved!'); }); HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Server Push Server Push Client Pull NodeJs + Web Socket Web Socket HTML5 HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Don’t Use AJAX Waste resources Slow down the server HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Web Socket Web Socket Client (Socket) Web Server “using NodeJS will push the notification to the clients which are connected to this server through Web Socket” HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. NodeJS + Web Socket fast and easy to use can use to build realtime applications HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Push Server Client Server Client: ! HTML5 App ( ) ! WebSocket Server Server: ! Server JSON Client ! Apache Server NodeJS Server ! NodeJS Apache+PHP HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Client: WebSocket var trigger = "updateContent"; $(document).ready(function(){ host = "localhost:8000"; conn = new WebSocket("ws://"+host+"/"); conn.onmessage = function(evt) { // Make an Ajax call to the server to update the content if (evt.data == "update"){ // Call the trigger function when there is an update window[trigger](); } }; conn.onerror = function() { }; conn.onclose = function() { conn = false; }; conn.onopen = function() { // alert("You are connected"); postMessage("You are connected"); }; } HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. AJAX function updateContent() { $.ajax({ type: "POST", url: "/phpserver/pages/get", data: [], error: function(qXHR, textStatus, errorThrown){ postMessage("There is an error while sending"); }, success: function(data){ if (data.res == "true"){ postMessage(data.data); } postMessage("Update new message"); } }); } HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. NodeJS: HTTP Server var sys = require("sys") , http = require("http") , fs = require("fs") , path = require("path") , ws = require('./lib/ws/server'); var httpServer = http.createServer(function(req, res){ if(req.method == "GET"){ if( req.url.indexOf("favicon") > -1 ){ res.writeHead(200, { 'Content-Type': 'image/x-icon', 'Connection': 'close' }); res.end(""); } else { res.writeHead(200, { 'Content-Type': 'text/html', 'Connection': 'close' }); res.write("Hello"); res.end(); } } else { res.writeHead(404); res.end(); } }); HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Server: WebSocket var server = ws.createServer({ server: httpServer }); server.addListener("listening", function(){ sys.log("Listening for connections."); }); // Handle WebSocket Requests server.addListener("connection", function(conn){ console.log('[*] open'); conn.addListener("message", function(message){ if (message == 'close') { console.log('[-] close requested') conn.close(); } else { console.log('[+] ', (new Buffer(message)).inspect()); server.broadcast("update"); } }); conn.addListener("close", function(){ console.log('[*] close'); }) }); server.addListener("disconnect", function(conn){ }); server.listen(8000); HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Routers http://localhost:8888/start?q=android&app=moko365 url.parse(string).pathname url.parse(string).query querystring(string)["foo"] querystring(string)["hello"] HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. start.js var http = require("http"); var url = require("url"); function start() { function onRequest(request, response) { var pathname = url.parse(request.url).pathname; console.log("Request for " + pathname + " received."); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World"); response.end(); } http.createServer(onRequest).listen(8888); console.log("Server has started."); } exports.start = start; HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. route.js function route(pathname) { console.log("About to route a request for " + pathname); } exports.route = route; HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Revision 2 of start.js var http = require("http"); var url = require("url"); function start(router) { function onRequest(request, response) { var pathname = url.parse(request.url).pathname; console.log("Request for " + pathname + " received."); route(pathname); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World"); response.end(); } http.createServer(onRequest).listen(8888); console.log("Server has started."); } exports.start = start; HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. index.js var server = require("./server"); var router = require("./router"); server.start(router.route); $ node index.js HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Request Handler var server = require("./server"); var router = require("./router"); var requestHandlers = require("./requestHandlers"); var handle = {} handle["/"] = requestHandlers.start; handle["/start"] = requestHandlers.start; server.start(router.route, handle); HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Revision 3 of start.js var http = require("http"); var url = require("url"); function start(router, handle) { function onRequest(request, response) { var pathname = url.parse(request.url).pathname; console.log("Request for " + pathname + " received."); route(handle, pathname); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World"); response.end(); } http.createServer(onRequest).listen(8888); console.log("Server has started."); } exports.start = start; HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Revision 2 of route.js function route(handle, pathname) { console.log("About to route a request for " + pathname); if (typeof handle[pathname] === 'function') { handle[pathname](); } else { console.log("No request handler found for " + pathname); } } exports.route = route; HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Revision 3 of route.js function route(handle, pathname) { console.log("About to route a request for " + pathname); if (typeof handle[pathname] === 'function') { return handle[pathname](); } else { console.log("No request handler found for " + pathname); return “Not found”; } } exports.route = route; HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. Revision 4 of start.js var http = require("http"); var url = require("url"); function start(router, handle) { function onRequest(request, response) { var pathname = url.parse(request.url).pathname; console.log("Request for " + pathname + " received."); response.writeHead(200, {"Content-Type": "text/plain"}); var respond = route(handle, pathname); response.write(respond); response.end(); } http.createServer(onRequest).listen(8888); console.log("Server has started."); } exports.start = start; HTML5 App Web Copyright (C) 2012 Moko365 Inc. All rights reserved. NodeJS Non-blocking requests Node.js process Spawn child process Proxying Node.js Protocol parser Advanced I/O handling
还剩72页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 6 金币 [ 分享pdf获得金币 ] 3 人已下载

下载pdf

pdf贡献者

世界之光

贡献于2013-05-05

下载需要 6 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf