当前位置:首页 » Android开发技术

为Android添加对WML的支持

2012-05-16 20:32 本站整理 浏览(6)


WML简介

WML(Wireless Markup Language - 无线标记语言)。它是一种从 HTML 继承而来的标记语言,但是 WML 基于 XML,因此它较 HTML 更严格。因为它比HTML 编写的内容要消耗网络浏览器更少的内存和CPU时间, 使得WML早期对广域网和移动设备来说更加友好。


WML的未来和WML在中国的现状

但是随着网络技术以及移动设备的快速迭代更新,WML相对于HTML,XHTML已经没有优势了,在越来越追求优秀用户体验的今天,WML的丑陋始终阻碍其发展,WML到最后肯定是会被舍弃和淘汰。 在国外,WML的使用越来越少,但是在国内,由于网络技术的慢国外一步,国内还有许多使用WML制作的WAP网站,所以在现阶段,浏览器支持WML还是很必要的。


webkit对WML的支持?

Android内置的浏览器采用webkit引擎,webkit默认是没有开放对WML支持的,而且在2011年4月28日的webkit开发日志上可以看到webkit已经决定不再支持WML,将其删除掉了:
2011-04-28 Adam Barth < abarth@webkit.org>
Reviewed by Eric Seidel.
Remove WML https://bugs.webkit.org/show_bug.cgi?id=59678 This patch removes WML from WebCore. After removing WML, there’s a 
bunch of twisted code that could be untwisted, but this patch contains 
only the purely mechanical part of removing the feature.
There’s been a lot of discussion on webkit-dev about whether we should 
remove WML. In addition to those threads, we’ve had an informal poll 
of the reviewers as well as an in-person discussion at the WebKit 
contributor’s meeting. Removing any feature is likely to make some 
folks unhappy, but, on balance, removing WML appears to be the right 
thing for the project to do at this time.

Android现在的webkit版本还没更新到最新,所有还保留有对WML的支持,需要自己修改开放它。网络上有很多关于使Android增加对WML支持的博文,不过其结果都是编译不通过,通过自己的不断尝试,终于成功了,但需要指出这样的修改能显示wml网页,进行平常的操作,但是不是full support wml。


Android增加对WML支持的步骤

1.在external/webkit/JavaScriptCore/wtf/Platform.h文件增加定义:
#define ENABLE_WML 1

2.修改external/webkit/WebCore/dom/DOMImplementation.cpp函数isXMLMIMEType(),使类型为WML以XML格式解析:
修改前:
bool DOMImplementation::isXMLMIMEType(const String& mimeType)
{
if (mimeType == "text/xml" || mimeType == "application/xml" || mimeType == "text/xsl")
......
修改后:
bool DOMImplementation::isXMLMIMEType(const String& mimeType)
{
if (mimeType == "text/xml" || mimeType == "application/xml" || mimeType == "text/xsl" || mimeType == "text/vnd.wap.wml")
......

3.修改external/webkit/WebCore/page/Console.cpp的lastWMLErrorMessage()函数:
#if ENABLE(WML)
String Console::lastWMLErrorMessage() const
{
Page* page = this->page();
if (!page)
return String();
#if ENABLE(INSPECTOR) // ---> 增加这一行
const Vector<ConsoleMessage*>& consoleMessages = page->inspectorController()->consoleMessages();
if (consoleMessages.isEmpty())
return String();
Vector<ConsoleMessage*>::const_iterator it = consoleMessages.begin();
const Vector<ConsoleMessage*>::const_iterator end = consoleMessages.end();
for (; it != end; ++it) {
ConsoleMessage* message = *it;
if (message->source() != WMLMessageSource)
continue;
return message->message();
}
#endif // ---> 增加这一行

4.修改external/webkit/WebCore/wml/WMLAElement.cpp文件:
(1).增加头文件WMLVariables.h:
#include "WMLVariables.h"

(2).修改defaultEventHandler函数为:
修改
String url = document()->completeURL(deprecatedParseURL(getAttribute(HTMLNames::hrefAttr)));
这一句为:

AtomicString href = getAttribute(HTMLNames::hrefAttr);
href = substituteVariableReferences(href,document(),WMLVariableEscapingEscape);
String url = document()->completeURL(deprecatedParseURL(href));

5.修改external/webkit/WebCore/Android.derived.jscbindings.mk,给变量FEATURE_DEFINES增加ENABLE_WML=1:
修改前:
FEATURE_DEFINES := ENABLE_ORIENTATION_EVENTS=1 ENABLE_TOUCH_EVENTS=1 ENABLE_DATABASE=1 ENABLE_OFFLINE_WEB_APPLICATIONS=1 ENABLE_DOM_STORAGE=1
 ENABLE_VIDEO=1 ENABLE_GEOLOCATION=1 ENABLE_CONNECTION=1 ENABLE_APPLICATION_INSTALLED=1
修改后:
FEATURE_DEFINES := ENABLE_ORIENTATION_EVENTS=1 ENABLE_TOUCH_EVENTS=1 ENABLE_DATABASE=1 ENABLE_OFFLINE_WEB_APPLICATIONS=1 ENABLE_DOM_STORAGE=1
 ENABLE_VIDEO=1 ENABLE_GEOLOCATION=1 ENABLE_CONNECTION=1 ENABLE_APPLICATION_INSTALLED=1 ENABLE_WML=1

6.修改external/webkit/WebCore/Android.derived.mk,给变量style_sheets增加$(LOCAL_PATH)/css/wml.css
修改前:
style_sheets := $(LOCAL_PATH)/css/html.css $(LOCAL_PATH)/css/quirks.css $(LOCAL_PATH)/css/view-source.css $(LOCAL_PATH)/css/mediaControls.css
 $(LOCAL_PATH)/css/mediaControlsAndroid.css
修改后:
style_sheets := $(LOCAL_PATH)/css/html.css $(LOCAL_PATH)/css/quirks.css $(LOCAL_PATH)/css/view-source.css $(LOCAL_PATH)/css/mediaControls.css
 $(LOCAL_PATH)/css/mediaControlsAndroid.css $(LOCAL_PATH)/css/wml.css

7.修改external/webkit/WebCore/Android.derived.v8bindings.mk,有两个地方:
(1).同第五条修改一致,给变量FEATURE_DEFINES增加ENABLE_WML=1:
修改前:
FEATURE_DEFINES := ENABLE_ORIENTATION_EVENTS=1 ENABLE_TOUCH_EVENTS=1 V8_BINDING ENABLE_DATABASE=1 ENABLE_OFFLINE_WEB_APPLICATIONS=1
 ENABLE_DOM_STORAGE=1 ENABLE_VIDEO=1 ENABLE_GEOLOCATION=1 ENABLE_CONNECTION=1 ENABLE_APPLICATION_INSTALLED=1
修改后:
FEATURE_DEFINES := ENABLE_ORIENTATION_EVENTS=1 ENABLE_TOUCH_EVENTS=1 V8_BINDING ENABLE_DATABASE=1 ENABLE_OFFLINE_WEB_APPLICATIONS=1
 ENABLE_DOM_STORAGE=1 ENABLE_VIDEO=1 ENABLE_GEOLOCATION=1 ENABLE_CONNECTION=1 ENABLE_APPLICATION_INSTALLED=1 ENABLE_WML=1

(2).在
# HTML tag and attribute names
GEN:= $(intermediates)/HTMLNames.cpp $(intermediates)/HTMLNames.h $(intermediates)/HTMLElementFactory.cpp
 $(intermediates)/HTMLElementFactory.h $(intermediates)/V8HTMLElementWrapperFactory.cpp $(intermediates)/V8HTMLElementWrapperFactory.h
$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
$(GEN): PRIVATE_CUSTOM_TOOL = perl -I $(PRIVATE_PATH)/bindings/scripts $< --tags $(PRIVATE_PATH)/html/HTMLTagNames.in
 --attrs $(PRIVATE_PATH)/html/HTMLAttributeNames.in --factory --wrapperFactoryV8 --output $(dir $@)
$(GEN): $(LOCAL_PATH)/dom/make_names.pl $(LOCAL_PATH)/html/HTMLTagNames.in $(LOCAL_PATH)/html/HTMLAttributeNames.in
$(transform-generated-source) // ---> this line must be the 'tab' start, otherwise, it doesn't work!!!!!!!!!
LOCAL_GENERATED_SOURCES += $(GEN)

之后增加WML中间tag和name解析文件的支持(这里也是本方案与网络上方案的区别,网络上是把这段加在Android.derived.mk中,导致WMLNames.h和WMLElementFactory.h无法生成):
# wml names
GEN:= $(intermediates)/WMLElementFactory.cpp $(intermediates)/WMLElementFactory.h $(intermediates)/WMLNames.cpp $(intermediates)/WMLNames.h
$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
$(GEN): PRIVATE_CUSTOM_TOOL = perl -I $(PRIVATE_PATH)/bindings/scripts $< --tags $(PRIVATE_PATH)/wml/WMLTagNames.in
 --attrs $(PRIVATE_PATH)/wml/WMLAttributeNames.in --factory --wrapperFactoryV8 --output $(dir $@)
$(GEN): $(LOCAL_PATH)/dom/make_names.pl $(LOCAL_PATH)/wml/WMLTagNames.in $(LOCAL_PATH)/wml/WMLAttributeNames.in
        $(transform-generated-source)//注意这里前面一定要有个tab,不然没有用,很重要!
LOCAL_GENERATED_SOURCES += $(GEN)

8.修改external/webkit/WebCore/Android.mk,将wml相关的解析文件增加到LOCAL_SRC_FILES变量中:
在css/RGBColor.cpp \之后增加如下内容:
wml/WMLAccessElement.cpp \
wml/WMLAElement.cpp \
wml/WMLAnchorElement.cpp \
wml/WMLBRElement.cpp \
wml/WMLCardElement.cpp \
wml/WMLDocument.cpp \
wml/WMLDoElement.cpp \
wml/WMLElement.cpp \
wml/WMLErrorHandling.cpp \
wml/WMLEventHandlingElement.cpp \
wml/WMLFieldSetElement.cpp \
wml/WMLFormControlElement.cpp \
wml/WMLGoElement.cpp \
wml/WMLImageElement.cpp \
wml/WMLImageLoader.cpp \
wml/WMLInputElement.cpp \
wml/WMLInsertedLegendElement.cpp \
wml/WMLIntrinsicEvent.cpp \
wml/WMLIntrinsicEventHandler.cpp \
wml/WMLMetaElement.cpp \
wml/WMLNoopElement.cpp \
wml/WMLOnEventElement.cpp \
wml/WMLOptGroupElement.cpp \
wml/WMLOptionElement.cpp \
wml/WMLPageState.cpp \
wml/WMLPElement.cpp \
wml/WMLPostfieldElement.cpp \
wml/WMLPrevElement.cpp \
wml/WMLRefreshElement.cpp \
wml/WMLSelectElement.cpp \
wml/WMLSetvarElement.cpp \
wml/WMLTableElement.cpp \
wml/WMLTaskElement.cpp \
wml/WMLTemplateElement.cpp \
wml/WMLTimerElement.cpp \
wml/WMLVariables.cpp \

9.修改external/webkit/Android.mk文件,将$(LOCAL_PATH)/WebCore/wml \增加到变量LOCAL_C_INCLUDES中:
在$(LOCAL_PATH)/WebCore/html \之后增加:
$(LOCAL_PATH)/WebCore/wml \

10.修改frameworks/base/core/java/android/webkit/LoadListener.java文件的handleHeaders()函数:
private void handleHeaders(Headers headers) {
                       ......
            } else if (mMimeType.equals("text/vnd.wap.wml")) {
                // As we don't support wml, render it as plain text
                //mMimeType = "text/plain"; //注释掉这句,让wml文件不已普通文本格式解析,而使用WML格式解析
            } else {
                       ......
    }


小提示

1.WML示例网站:waptt.com
2.此修改基于Android2.3源码