Android and HTML5 开发手机应用

来源:互联网 发布:php防cc攻击代码 编辑:程序博客网 时间:2024/05/22 09:00

一、离线应用缓存 HTML 5 Offline Application Cache

  • 在服务器上添加MIME TYPE支:text/cache-manifest

    如果在Apache下添加:

    1AddType text/cache-manifest manifest

    如果为Nginx,在添加:

    1text/cache-manifest                   manifest;

    或者通过动态程序生成:

    1header('Content-type: text/cache-manifest; charset=UTF-8');
  • 创建 NAME.manifest:

    新建清单文件 manifest

    01CACHE MANIFEST
    02# This is a comment.
    03# Cache manifest version 0.0.1
    04# If you change the version number in this comment,
    05# the cache manifest is no longer byte-for-byte
    06# identical.
    07 
    08/app/static/default/js/models/prototype.js
    09/app/static/default/js/controllers/init.js
    10 
    11NETWORK:
    12# All URLs that start with the following lines
    13# are whitelisted.
    14 
    15http://a.com/
    16 
    17CACHE:
    18# Additional items to cache.
    19/app/static/default/images/main/bg.png
    20 
    21FALLBACK:
    22demoimages/ images/
  • 给 <html> 标签加 manifest 属性

    建立manifest文件之后,需要在HTML文档中声明:
    声明清单文件 manifest

    <!doctype html> <html manifest="notebook.manifest">     <head>         <meta charset="UTF-8" /> <meta name = "viewport" content = "width = device-width, user-scalable = no">         <title>NoteBook</title>     </head>     <body>     </body> </html>

二、Key-Value Storage

三、Using the JavaScript Database

四、Android下使用WebView来做基于HTML5的App

见如下AndroidManifest.xml

01< ?xml version="1.0" encoding="utf-8"?>
02<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.xinze.joke" android:versioncode="1"android:versionname="1.0">
03    <application android:icon="@drawable/icon"android:label="@string/app_name">
04        <activity android:name=".Joke"android:label="@string/app_name"android:configchanges="orientation|keyboardHidden|navigation"android:theme="@android:style/Theme.NoTitleBar">
05            <intent -filter="">
06                <action android:name="android.intent.action.MAIN">
07                <categoryandroid:name="android.intent.category.LAUNCHER">
08            </category></action></intent>
09        </activity>
10    </application>
11    <uses -permission="" android:name="android.permission.INTERNET">
12</uses></manifest>

注意:

1<uses -permission="" android:name="android.permission.INTERNET"></uses>

, 允许网络应用,必须!!

Android主程序代码:

001package com.xinze.joke;
002 
003import android.app.Activity;
004import android.app.AlertDialog;
005import android.app.AlertDialog.Builder;
006 
007import android.content.DialogInterface;
008 
009import android.os.Bundle;
010import android.view.KeyEvent;
011import android.view.View;
012import android.view.Window;
013import android.view.WindowManager;
014import android.webkit.JsPromptResult;
015import android.webkit.JsResult;
016import android.webkit.WebChromeClient;
017import android.webkit.WebView;
018import android.webkit.WebViewClient;
019 
020import android.webkit.WebStorage ;
021 
022public class Joke extends Activity {
023 
024    /** Called when the activity is first created. */
025    @Override
026    public void onCreate(Bundle savedInstanceState) {
027        super.onCreate(savedInstanceState);
028 
029        final WebView wv = new WebView(this);
030 
031        // 覆盖默认后退按钮的作用,替换成WebView里的查看历史页面
032        wv.setOnKeyListener(new View.OnKeyListener() {
033 
034            @Override
035            public boolean onKey(View v, int keyCode, KeyEvent event) {
036                if (event.getAction() == KeyEvent.ACTION_DOWN) {
037                    if ((keyCode == KeyEvent.KEYCODE_BACK) && wv.canGoBack()) {
038                        wv.goBack();
039                        return true;
040                    }
041                }
042                return false;
043            }
044        });
045 
046        // 设置支持Javascript
047        wv.getSettings().setJavaScriptEnabled(true);
048 
049        wv.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
050        wv.getSettings().setDatabaseEnabled(true);
051        wv.getSettings().setDatabasePath("/data/data/com.xinze.joke/databases");
052 
053        // 创建WebViewClient对象
054        WebViewClient wvc = new WebViewClient() {
055 
056            @Override
057            public boolean shouldOverrideUrlLoading(WebView view, String url) {
058                wv.loadUrl(url);
059                // 记得消耗掉这个事件。给不知道的朋友再解释一下,Android中返回True的意思就是到此为止吧,事件就会不会冒泡传递了,我们称之为消耗掉
060                return true;
061            }
062        };
063 
064        // 设置WebViewClient对象
065        wv.setWebViewClient(wvc);
066 
067        // 创建WebViewChromeClient
068        WebChromeClient wvcc = new WebChromeClient() {
069 
070            // 处理Alert事件
071            @Override
072            public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
073                // 构建一个Builder来显示网页中的alert对话框
074                Builder builder = new Builder(Joke.this);
075                builder.setTitle("笑死不偿命");
076                builder.setMessage(message);
077                builder.setPositiveButton(android.R.string.ok, newAlertDialog.OnClickListener() {
078                    @Override
079                    public void onClick(DialogInterface dialog, intwhich) {
080                        result.confirm();
081                    }
082                });
083                builder.setCancelable(false);
084                builder.create();
085                builder.show();
086                return true;
087            }
088 
089            // 处理Confirm事件
090            @Override
091            public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
092                Builder builder = new Builder(Joke.this);
093                builder.setTitle("删除确认");
094                builder.setMessage(message);
095                builder.setPositiveButton(android.R.string.ok, newAlertDialog.OnClickListener() {
096 
097                    @Override
098                    public void onClick(DialogInterface dialog, intwhich) {
099                        result.confirm();
100                    }
101 
102                });
103                builder.setNeutralButton(android.R.string.cancel, newAlertDialog.OnClickListener() {
104 
105                    @Override
106                    public void onClick(DialogInterface dialog, intwhich) {
107                        result.cancel();
108                    }
109 
110                });
111                builder.setCancelable(false);
112                builder.create();
113                builder.show();
114                return true;
115            }
116 
117            // 处理提示事件
118            @Override
119            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,
120                    JsPromptResult result) {
121                // 看看默认的效果
122                return super.onJsPrompt(view, url, message, defaultValue, result);
123            }
124 
125            @Override
126               public void onExceededDatabaseQuota(String url, String
127                       databaseIdentifier, long currentQuota, longestimatedSize, long
128                       totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
129                                       quotaUpdater.updateQuota(204801);
130                                   }
131 
132        };
133 
134        wv.loadUrl("http://192.168.1.14/index.html");
135 
136        // 设置setWebChromeClient对象
137        wv.setWebChromeClient(wvcc);
138        setContentView(wv);
139    }
140}

使用 JavaScript Database 的时候,需要特别注意:setDatabaseEnabled 以及 onExceededDatabaseQuota!