`
quanminchaoren
  • 浏览: 926508 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Android 编译文件使其支持wml

阅读更多

前不久发现android默认没有放开对wml的支持,这样就导致某些网站无法访 问,从网上搜索到的文档都说只要ENABLE_WML=1就可以支持,但是我把ENABLE_WML设置成1之后,就出现了编译通不过的情况,经过一番调 试,最终可以编译并且实现了对wml的支持。

 

2. Windows

必备条件把Webkit编译通过了,具体参考webkit.org上的说明,把必须的SDK,patch都安装了。

VC2005和VC Express 2005都能编过,安装VC的几个patch能大大提升编译速度,磨刀不误砍柴功。

编译成功后默认wml是关闭的,修改如下几个文件,把wml相关配置(ENABLE_WML)打开

FeatureDefines.xcconfig
GNUmakefile.am
configure.ac
features.pri
FeatureDefines.vsprops

这时开始编译,必然会失败,停在webcore编译上,提示如下:

WMLElementFactory.cpp 中ConstructorFunction重定义

然后关键的两步:

1.找到DerivedSources.cpp,注释掉如下两行

//#include "WMLElementFactory.cpp"
//#include "WMLNames.cpp"

2. 修改webcore.vcproj,把上面两个文件参与编译(关闭“从生成中排除”)。

这样就能编译成功了。

 

   下面主要纪录一下如何编译通过,编译不通过一开始都是说找不到WMLNames.h之类的错误,所以我们需要在脚本里面添加上生成该文件的语句,并且把wml里面的头文件都include进来。

     首先在external/webkit下的Android.mk 中添加

      LOCAL_C_INCLUDES := $(LOCAL_C_INCLUDES) /
                    $(LOCAL_PATH)/WebCore/wml

 
D:\Webkit\WebCore\Android.derived.mk
     然后在Android.derived.mk中添加wml的user agent style sheets

     style_sheets := $(style_sheets) $(LOCAL_PATH)/css/wml.css

 

     参考XMLNames.cpp的生成方式,生成wml对应的WMLNames.cpp .h等

ifeq ($(ENABLE_WML), true)
GEN:= $(intermediates)/WMLNames.cpp $(intermediates)/WMLNames.h $(intermediates)/WMLElementFactory.cpp $(intermediates)/WMLElementFactory.h
$(GEN): PRIVATE_PATH := $(LOCAL_PATH)
$(GEN): PRIVATE_CUSTOM_TOOL = perl -I $(PRIVATE_PATH)/bindings/scripts $< --tags $(wml_tag) --attrs $(wml_attrs) --factory --wrapperFactory --output $(dir $@)
$(GEN): wml_tag := $(LOCAL_PATH)/wml/WMLTagNames.in
$(GEN): wml_attrs := $(LOCAL_PATH)/wml/WMLAttributeNames.in
$(GEN): $(LOCAL_PATH)/dom/make_names.pl $(wml_tag) $(wml_attrs)
$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
endif
 
    这样在out目录下就会生成WMLNames.cpp等文件

    当然同样需要把webkit/webcore/wml下的文件都添加的Android.mk中来编译。

  
    要让android支持wml,还需要进行一些代码方面的修改

 

  对于移动终端,有时候服务器返回的是WML格式的页面。 比如说中国移动的一些需要使用cmwap接入点的业务页面(DCD, 移动梦网…), 这就要求终端浏览器必须能够支持对WML格式页面的解析和显示。 Android原始代码里的webkit层虽然提供了WML相关的解析类,但是并没有很好地支持,所以在页面上无法正确显示。 我们需要做以下一些修改:
       1. 打开对WML格式解析的通道
       修改源码的\external\webkit\WebCore\dom\DOMImplementation.cpp 获取到服务器返回的数据中的content-type字段值后,会调用这个类里面的isXMLMIMEType()方法来判断是否按照XML格式来解析。 我们看这个方法:
java代码:

  1. bool DOMImplementation::isXMLMIMEType(const String& mimeType)
  2. {
  3. if (mimeType == "text/xml" || mimeType == "application/xml" || mimeType == "text/xsl")
  4. return true;
  5. static const char* const validChars = "[0-9a-zA-Z_\\-+~!$\\^{}|.%'`#&*]"; // per RFCs: 3023, 2045
  6. DEFINE_STATIC_LOCAL(RegularExpression, xmlTypeRegExp, (String("^") + validChars + "+/" + validChars + "+\\+xml$", TextCaseSensitive));
  7. return xmlTypeRegExp.match(mimeType) > -1;
  8. }

复制代码

       这里只包含了text/xml, application/xml, text/xls. 我们需要把WML相应的MiMeType类型加进去
If(mimeType == “text/vnd.wap.wml”) return true;
       修改framework/base/core/java/android/webkit/LoadListener.java, 源码如下:
java代码:

  1. // Does the header parsing work on the WebCore thread.
  2. private void handleHeaders(Headers headers) {
  3. } else if (mMimeType.equals("text/vnd.wap.wml")) {
  4. // As we don't support wml, render it as plain text
  5. mMimeType = "text/plain";
  6. }

复制代码

       我们可以看到, 原来是不支持wml格式的, 都当做text/plain来处理了,这样显然是不能正确显示的。 所以这一行mMimeType = "text/plain";需要注释掉,打开给外围。
       2. 对WML中的超链接元素(WMLAElement和WMLAnchorElement)中href属性值里面的变量替换。
笔 者发现,在一个WML的登陆页面上,填入用户名和密码后,点击登陆,附加到url后面的用户名和密码是$(username) 和$(password) ,有web开发经验的XDJM都知道,这是没有将变量替换为页面上相应值。我们看WMLAElement.cpp中处理点击事件的方法:
java代码:

  1. void WMLAElement::defaultEventHandler(Event* event)
  2. {
  3. if (isLink() && (event->type() == eventNames().clickEvent || (event->type() == eventNames().keydownEvent && focused()))) {
  4. MouseEvent* e = 0;
  5. if (event->type() == eventNames().clickEvent && event->isMouseEvent())
  6. e = static_cast<MouseEvent*>(event);
  7. KeyboardEvent* k = 0;
  8. if (event->type() == eventNames().keydownEvent && event->isKeyboardEvent())
  9. k = static_cast<KeyboardEvent*>(event);
  10. if (e && e->button() == RightButton) {
  11. WMLElement::defaultEventHandler(event);
  12. return;
  13. }
  14. if (k) {
  15. if (k->keyIdentifier() != "Enter") {
  16. WMLElement::defaultEventHandler(event);
  17. return;
  18. }
  19. event->setDefaultHandled();
  20. dispatchSimulatedClick(event);
  21. return;
  22. }
  23. if (!event->defaultPrevented() && document()->frame()) {
  24. String url = document()->completeURL(deprecatedParseURL(getAttribute(HTMLNames::hrefAttr)));
  25. document()->frame()->loader()->urlSelected(url, target(), event, false, false, true, SendReferrer);
  26. }
  27. event->setDefaultHandled();
  28. }
  29. WMLElement::defaultEventHandler(event);

复制代码

       通过打印Log发现,getAttribute(HTMLNames::hrefAttr)获取的只是href后面的字符串,包含变量$(). 我们需要对其中的变量进行转化。还好WMLVariables里面已经提供了相应的方法substituteVariableReferences,不需 要我们再去写一个了。修改如下
java代码:

  1. #include "WMLVariables.h"
  2. if (!event->defaultPrevented() && document()->frame()) {
  3. // Substitute variables within target url attribute value. String href = getAttribute(HTMLNames::hrefAttr);
  4. href = substituteVariableReferences(href, document(), WMLVariableEscapingEscape);
  5. String url = document()->completeURL(deprecatedParseURL(href));
  6. document()->frame()->loader()->urlSelected(url, target(), event, false, false, true, SendReferrer);
  7. }

复制代码

       别忘了,WMLAnchorElement.cpp中相应的地方也要同样改掉。
  3. 在页面上长按链接时弹出选项点击失效
       这是由于点击时是从webkit层去获取这个链接的地址和标题的, 而源码中只考虑了HTML格式的页面, WML页面被忽略了。 返回的href为null.
       首先要在WMLAElement.cpp中提供接口, 返回链接。
java代码:

  1. KURL WMLAElement::href() const
  2. {
  3. // Substitute variables within target url attribute value.
  4. String href = substituteVariableReferences(getAttribute(HTMLNames::hrefAttr),
  5. document(), WMLVariableEscapingEscape);
  6. return document()->completeURL(href);
  7. }

复制代码

        由于WMLAnchorElement继承了WMLAElement, 就不需要再添加这个方法了。 然后修改WebViewCore.cpp, 原来获取href的方法是这样的:
java代码:

  1. WebCore::String WebViewCore::retrieveHref(WebCore::Frame* frame, WebCore::Node* node)
  2. {
  3. WebCore::HTMLAnchorElement* anchor = retrieveAnchorElement(frame, node);
  4. return anchor ? anchor->href() : WebCore::String();
  5. }

复制代码

在这里增加WML的支持, 修改如下:
java代码:

  1. #if ENABLE(WML)
  2. WebCore::WMLAnchorElement* WebViewCore::retrieveWMLAElement(WebCore::Frame* frame, WebCore::Node* node)
  3. {
  4. if (!CacheBuilder::validNode(m_mainFrame, frame, node))
  5. return 0;
  6. if (!node->hasTagName(WebCore::WMLNames::aTag))
  7. return 0;
  8. return static_cast<WebCore::WMLAnchorElement*>(node);
  9. }
  10. #endif
  11. /**add WML anchor support 20110224, end**/
  12. WebCore::String WebViewCore::retrieveHref(WebCore::Frame* frame, WebCore::Node* node)
  13. {
  14. /**retrieve WMLAnchor element. 20110224, begin**/
  15. #if ENABLE(WML)
  16. if (node->isWMLElement()) {
  17. WebCore::WMLAnchorElement* anchor = retrieveWMLAElement(frame, node);
  18. return anchor ? anchor->href() : WebCore::String();
  19. }
  20. #endif
  21. /**retrieve WMLAnchor element. 20110224, end**/
  22. WebCore::HTMLAnchorElement* anchor = retrieveAnchorElement(frame, node);
  23. return anchor ? anchor->href() : WebCore::String();
  24. }

复制代码

       还有获取链接标题的方法,修改如下:
java代码:

  1. WebCore::String WebViewCore::retrieveAnchorText(WebCore::Frame* frame, WebCore::Node* node)
  2. {
  3. /**retrieve WMLAnchor element. 20110224, begin**/
  4. #if ENABLE(WML)
  5. if (node->isWMLElement()) {
  6. WebCore::WMLAnchorElement* anchor = retrieveWMLAElement(frame, node);
  7. return anchor ? anchor->title() : WebCore::String();
  8. }
  9. #endif
  10. /**retrieve WMLAnchor element. 20110224, end**/
  11. WebCore::HTMLAnchorElement* anchor = retrieveAnchorElement(frame, node);
  12. return anchor ? anchor->text() : WebCore::String();
  13. }

复制代码

4. 移动梦网无法正确显示,解析出错。
       移动梦网返回的数据格式为application/vnd.wap.xhtml+xml, 包含了xhtml和xml两种格式。而CMCC的数据本身又不是严格按照W3C标准来的, 导致在解析的时候出现了语法错误提示。 对于这种情况,我们显然无法去要求CMCC改变数据, 只能把这种格式当做普通的html来显示, html没有那么严格的语法检查, 可以正常显示。修改framework/base/core/java/android/webkit/LoadListener.java:
java代码:

  1. private void handleHeaders(Headers headers) {
  2. 。。。
  3. String contentType = headers.getContentType();
  4. if (contentType != null) {
  5. parseContentTypeHeader(contentType);
  6. // If we have one of "generic" MIME types, try to deduce
  7. // the right MIME type from the file extension (if any):
  8. if (mMimeType.equals("text/plain") ||
  9. mMimeType.equals("application/octet-stream")) {
  10. // for attachment, use the filename in the Content-Disposition
  11. // to guess the mimetype
  12. String contentDisposition = headers.getContentDisposition();
  13. String url = null;
  14. if (contentDisposition != null) {
  15. url = URLUtil.parseContentDisposition(contentDisposition);
  16. }
  17. if (url == null) {
  18. url = mUrl;
  19. }
  20. String newMimeType = guessMimeTypeFromExtension(url);
  21. if (newMimeType != null) {
  22. mMimeType = newMimeType;
  23. }
  24. } else if (mMimeType.equals("text/vnd.wap.wml")) {
  25. // As we don't support wml, render it as plain text
  26. // mMimeType = "text/plain";
  27. } else {
  28. // It seems that xhtml+xml and vnd.wap.xhtml+xml mime
  29. // subtypes are used interchangeably. So treat them the same.
  30. //if (mMimeType.equals("application/vnd.wap.xhtml+xml")) {
  31. // mMimeType = "application/xhtml+xml";
  32. //}
  33. /* Webkit used libxml2 as the xml parser, but the CMCC's WAP sites
  34. written in WML or XHTML do not meet W3C's specification well,
  35. and libxml2 will throw a lot of grammatical errors when it parses
  36. the document which has the mime type is "application/xhtml+xml" or
  37. "application/vnd.wap.xhtml+xml". When i opened the macro named
  38. "XHTMLMP" in config.h in webcore and tested, i found some bugs,
  39. i believed that Google did not do detail test works for this macro.
  40. So i could handle "XHTML" mime type as "HTML" only in order to
  41. open CMCC's WAP sites in browser.
  42. */
  43. if (mMimeType.equals("application/vnd.wap.xhtml+xml") ||
  44. mMimeType.equals("application/xhtml+xml"))
  45. {
  46. mMimeType = "text/html";
  47. }

复制代码

 

WebKit支持WML,可现在这句话需要打个折扣了,变成“WebKit曾经支持WML”。

一直以来,WebKit的ENABLE(WML)开关默认是关闭的,需要在编译时打开才能提供WML的支持。苹果在iPhone的Safari上一直都不支持WML,谷歌在Android的Chrome Lite也是不支持WML的。

如 果你去查看WebKit的最新源代码,你会发现原来的wml目录没有了,不管是源码的wml还是测试用例的wml,都没有了。查询WebKit的开发日 志,可以在2011年4月28日的记录上看到相关信息,Remove 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.

这次的代码提交对应的版本号是85256,移除了WebCore下的WML支持。

2.3.5

_____________________________________________________________________________________________

使用VS2005编译库:
1. 下载Qt源码并解压(qt-win-opensource-src-4.5.3.zip);

2. 安装vs2005,win7自动更新到最新补丁!!!

3. 启动vs2005,选中“工具”,“visual studio 命令提示”

3. 进入解压目录,键入

     configure -platform win32-msvc2005 -opensource -nomake examples -nomake demos
4. 编译成功后,在vs2005中打开解压目录下的 project.sln。设置 browser 为启动项目,编译真个工程即可。

如果运行时没找到dll。只要拷贝到同一个目录下执行。

 

支持wml版本:

1,打开E:\projects\webkit\src\src\3rdparty\webkit\WebCore\WebCore.pro

(最终生成E:\projects\webkit\src\src\3rdparty\webkit\WebCore\QtWebKit.vcproj)

将 !contains(DEFINES, ENABLE_WML=.): DEFINES += ENABLE_WML=0

由0改为1.

2, 用

configure -platform win32-msvc2005 -opensource -nomake examples -nomake demos

编译。

3,

注意使用的编译器是哪个版本的:

E:\projects\webkit\src> configure -platform win32-msvc2005 -opensource -nomake e
xamples -nomake demos
Found more than one known compiler! Using "Microsoft (R) 32-bit C/C++ Optimizing
Compiler.NET 2005 (8.0)"

This is the Qt for Windows Open Source Edition.

You are licensed to use this software under the terms of
the GNU General Public License (GPL) version 3
or the GNU Lesser General Public License (LGPL) version 2.1.

Type '3' to view the GNU General Public License version 3 (GPLv3).
Type 'L' to view the Lesser GNU General Public License version 2.1 (LGPLv2.1).
Type 'y' to accept this license offer.
Type 'n' to decline this license offer.

分享到:
评论

相关推荐

    支持WML的浏览器,可以进行手机上网~!支持HTTP协议!

    WML是专门为无线设备如早期的手机设计的一种标记语言,它简化了网页内容,使其能够在低带宽和有限显示空间的设备上浏览。 描述中提到的“支持WML1.0和WML1.1协议”,意味着这款浏览器兼容这两种WML版本,这在早期...

    WML语言参考教程 WML

    总之,WML语言是移动互联网早期的重要工具,尽管现在已经被更先进的技术所替代,但理解其基本概念有助于我们理解移动设备上的网页开发历史,以及当前流行的移动优化技术的演变。通过深入学习和实践,初学者可以迅速...

    WML(无线标记语言)

    WML程序本质上是纯文本文件,遵循XML的结构。下面是一个简单的WML程序示例: ```xml &lt;!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml"&gt; &lt;wml&gt; &lt;p&gt;Hello World!...

    nokia手机1511固件支持WML网页格式插件

    在这款手机中,固件特别支持了WML(Wireless Markup Language)网页格式,这是一种专为低带宽无线通信设计的标记语言,使得用户可以在手机上浏览简化的网页内容。 **WML简介** WML是XML的子集,主要针对早期的移动...

    WML语法大全WMLScript语法大全

    WML遵循XML的字符集,即ISO/IEC-10646(Unicode 2.0),并支持其子集,如US-ASCII、ISO-8859-1或UTF-8。在WML中,大小写是敏感的,所有标签、属性和枚举属性必须使用小写字母。参数名称和值也区分大小写,例如,`...

    Learning WML & WML Script

    《Learning WML & WML Script》是一本由Martin Frost编写的书籍,专注于介绍无线标记语言(WML)和WML脚本,适用于那些希望在移动通信领域开发内容的开发者。WML是Wireless Markup Language的缩写,是为无线应用平台...

    编写wml的简单工具

    6. **导出和上传**:Waptor23.exe可能支持直接导出WML文件,并提供上传至服务器的功能,简化了发布流程。 **文件使用说明.url** 这个文件名暗示它是一个URL快捷方式,很可能指向一个在线的使用指南或者开发者文档,...

    wap wml

    一个基本的WML文件包括文件声明、元素、属性和注释。文件声明通常以`&lt;?xml version="1.0"?&gt;`和DOCTYPE声明开始,定义WML的版本和使用的DTD。元素是WML的构建块,可以是带有内容的开始和结束标签,如`&lt;tag&gt;content...

    HTML到WML格式转换

    4. 压缩内容:考虑到无线网络的带宽限制,WML页面通常需要进行压缩,去除不必要的空格和注释,减小文件大小。 5. 测试与调试:转换完成后,需要在实际的无线设备或模拟器上测试,确保页面能正常显示并具有良好的...

    wml教程及常用功能介绍

    在`wml补充.txt`、`wml下.txt`、`wml中.txt`和`wml上.txt`这四个文件中,可能包含了各种WML实践案例,比如基本的卡片布局、表单处理、动态内容生成等。通过逐个阅读这些案例,你可以更深入地理解WML的实际应用。 **...

    WML 详细中文教程

    每个WML文档都是一个.xml文件,扩展名为.wml。 2. **WML标签**:WML标签分为元素标签(Element)和属性标签(Attribute)。例如,`&lt;card&gt;`定义了一个卡片,`&lt;p&gt;`用于创建段落,`&lt;go&gt;`用于链接,`&lt;input&gt;`用于用户...

    wml详细讲解(exe+word)

    在提供的文件中,"1in256b5hwc5.doc"可能是包含WML理论或实践教程的Word文档,而"WML.exe"可能是一个模拟WAP环境的执行文件,用于实践操作和测试WML代码。通过学习这两个文件,你可以深入理解WML的语法、结构和在...

    WML1.1协议标准

    4. **表单处理**:WML支持简单的表单元素,如`&lt;input&gt;`、`&lt;select&gt;`、`&lt;option&gt;`等,用于用户输入和数据提交。 5. **变量与脚本**:WML1.1通过`&lt;var&gt;`元素可以创建变量,但不支持复杂的脚本语言,通常配合WAP网关的...

    wml转换为html

    在压缩包文件`wmltest`中,可能包含了一个或多个WML文件和相应的XSLT样式表,用于演示或练习这个转换过程。通过解压并应用上述方法,可以观察转换前后文件的差异,加深对WML到HTML转换的理解。 总之,XSLT是一种...

    WMLScript语言基础(语法,函数,变量,操作)

    函数 语句 一个WMLScript 函数作为一个WMLScript 编译单元(编译单元通常是一个WMLScript文件)的一部分,通过名字来标识,可以被其他函数调用而进行一系列的操作,并返回一个值。下面如何声明并调用函数...

    关于wml的常见问题解答

    首先,WML的文件大小较小,所需带宽少,这对于无线网络尤为重要,因为在很长一段时间内,无线网络的带宽相对有限。其次,WML对处理器的要求较低,这有助于节省电池寿命,考虑到移动设备的能源供应有限,这一点至关...

    wml.rar_WML

    在“wml.rar_WML”这个压缩包中,包含了一个名为“wml.wml”的文件,展示了WML的基本结构和功能,以及两种列表和后退、提交功能的应用。 WML的核心是Deck,一个Deck由一个或多个卡片(Card)组成,就像传统的网页由...

    wml介绍,简单易懂,纯word文档

    - **WML Deck文件**:通常以`.wml`扩展名存储,包含一个或多个WML卡片。 **WML语法特点:** 1. **元素与属性**:WML元素使用尖括号`&lt; &gt;`包围,如`&lt;card&gt;`。每个元素都有开始标签和结束标签,如`&lt;card&gt;...&lt;/card&gt;`。...

    wml入门教程

    1. **编写WML脚本**:使用任何文本编辑器,如Notepad或更高级的代码编辑器,开始编写WML文件。例如,下面的代码展示了简单的WML页面结构: ```xml &lt;!DOCTYPE wml PUBLIC "-//PHONE.COM//DTD WML 1.1//EN" ...

Global site tag (gtag.js) - Google Analytics