lizongbo at 618119.com 工作,生活,Android,前端,Linode,Ubuntu,nginx,java,apache,tomcat,Resin,mina,Hessian,XMPP,RPC

2011年08月21日

手机wap网站开发过程中通过dtd校验来检查wap1.0和wap2.0的页面语法

Filed under: Xhtml — 标签:, , , , , , , — lizongbo @ 13:40

手机wap网站开发过程中通过dtd校验来检查wap1.0和wap2.0的页面语法

对手机wap网站的wap1.0和wap2.0页面内容进行dtd的校验非常有价值,既可以保证页面对移动终端的兼容性,也能促使开发人员写出高质量的代码。

以前早期在做普通web页面开发的时候,对html的语法一知半解就开搞,标签不闭合,嵌套错误等问题从来没注意过,只管在IE6里打开能正常显示即可,
结果带来的后果就是在页面某个位置需要插入一段新内容时,整个页面就错位了,变得非常难看,也不知道怎么样来搞好,痛苦万分。

后来进行的是wap页面开发,wap页面用的是wap1.0的xml,加上各种山寨手机对wap页面的解析可不像电脑上的浏览器那样可以对错误的写法进行兼容,于是各种兼容性问题就出来了。
因此学会了用m3gate打开页面进行检查,只有m3gate打开时不出错的页面,才能放心的在各种山寨上正常显示而不出错。
再到后来,经过学习和总结,发现m3gate的检查其实和dtd校验的效果是一样的,于是摸索出通过dtd校验来发现标签嵌套错误等问题。

移动终端的发展是日新月异,很快就进入到了wap2.0时代,当然这个时候的手机浏览器对wap2.0的兼容性就好多了。
一些小的错误,也能兼容掉,但是难免也出现莫名其妙的错误,由于wap2.0的xml元素定义用的也还是dtd,因此继续用dtd校验来搞定。

wap1.0和wap2.0的自动化监控校验流程如下:
测试工具访问各个页面,获取对应的xml内容,保存为字符串,然后将页面的dtd声明部分,替换为对应的本地声明映射(这样避免联网获取dtd文件而影响性能),
生成新的字符串,然后使用java的xml parser进行解析,解析过程中如果有抛出各种异常,那就是把页面内容有错的地方全部揪出来了,再通知开发人员进行页面内容的bug修复。
通常比如img元素缺少alt属性等问题都可以及时发现。

正式环境则通过自动化监控脚本定期访问业务进行检查。

进行dtd校验的相关代码如下:

1.将远程的dtd等实体解析映射到本地的LocalEntityResolver(自动化监控中是通过字符串替换来将dtd的声明替换为本地路径,我是直接通过EntityResolver来进行映射):

[code]
package com.lizongbo.xml;

import java.io.IOException;

import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
* 将xml组件依赖的远程的schema文件都映射到本地
*
* @author lizongbo
*
*/
public class LocalEntityResolver implements EntityResolver {

@Override
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
System.out.println(“publicId==” + publicId + “,systemId==” + systemId);
if (“-//W3C//DTD XHTML 1.0 Strict//EN”.equals(publicId)) {
String url = “/com/lizongbo/web/validation/dtds/www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”;
System.out.println(systemId + ” LocalEntityResolver yyyy map to:”
+ url);
System.out.println(String.class.getResource(url));
if (String.class.getResource(url) != null) {
InputSource is = new InputSource(
String.class.getResourceAsStream(url));
is.setPublicId(publicId);
is.setSystemId(systemId);
return is;
}
}
if (systemId != null) {
String ids[] = new String[] { “/xhtml-attribs-1.mod”,
“/xhtml-notations-1.mod”, “/xhtml-datatypes-1.mod”,
“/xhtml-qname-1.mod”, “/xhtml-mobile10-model-1.mod”,
“/xhtml-mobile10-model-1.mod”, “xhtml-charent-1.mod”,
“/xhtml-symbol.ent”, “/xhtml-lat1.ent”,
“/xhtml-special.ent”, “/xhtml-inlstruct-1.mod”,
“/xhtml-inlphras-1.mod”, “/xhtml-blkstruct-1.mod”,
“xhtml-blkphras-1.mod”, “/xhtml-lat1.ent”,
“/xhtml-lat1.ent” };

for (int i = 0; i < ids.length; i++) {
if (systemId.endsWith(ids[i])) {
String url = “/com/lizongbo/web/validation/dtds/www.w3.org/xhtml-modularization/DTD/”
+ systemId.substring(systemId.lastIndexOf(“/”) + 1);
System.out.println(” local ” + systemId + ” try map to:”
+ url);
if (String.class.getResource(url) == null) {
url = “/com/lizongbo/web/validation/dtds/www.w3.org/TR/xhtml-modularization/DTD/”
+ systemId
.substring(systemId.lastIndexOf(“/”) + 1);
System.out.println(” local ” + systemId
+ ” retry map to:” + url);
}
if (String.class.getResource(url) == null) {
url = “/com/lizongbo/web/validation/dtds/www.wapforum.org/DTD/”
+ systemId
.substring(systemId.lastIndexOf(“/”) + 1);
System.out.println(” local ” + systemId
+ ” retry map to:” + url);
}
System.out.println(“try get ”
+ String.class.getResource(url));
if (String.class.getResource(url) != null) {
InputSource is = new InputSource(
String.class.getResourceAsStream(url));
is.setPublicId(publicId);
is.setSystemId(systemId);
return is;
}
}
}
if (systemId.endsWith(“.xsd”)) {
String url = “/com/lizongbo/web/validation/xsds/”
+ systemId.replace(“http://”, “”);
System.out.println(systemId + ” LocalEntityResolver 22 map to:”
+ url);
System.out.println(String.class.getResource(url));
if (String.class.getResource(url) != null) {
InputSource is = new InputSource(
String.class.getResourceAsStream(url));
is.setPublicId(publicId);
is.setSystemId(systemId);
return is;
}
} else {
String url = “/com/lizongbo/web/validation/dtds/”
+ systemId.replace(“http://”, “”);
System.out.println(systemId + ” LocalEntityResolver 11 map to:”
+ url);
System.out.println(String.class.getResource(url));
if (String.class.getResource(url) == null) {
url = “/com/lizongbo/web/validation/dtds/www.w3.org/TR/xhtml-modularization/DTD/”
+ systemId.replace(“http://”, “”);
System.out.println(” local ” + systemId + ” retry map to:”
+ url);
}
if (String.class.getResource(url) != null) {
InputSource is = new InputSource(
String.class.getResourceAsStream(url));
is.setPublicId(publicId);
is.setSystemId(systemId);
return is;
}
}
}
return null;
}
}

[/code]

2.实际校验的代码:
[code]
package com.lizongbo.xml;

import java.io.*;
import java.net.*;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.*;

/**
* DTD校验工具类
*
* @author lizongbo
*
*/
public class DTDUtil {

/**
* @param args
* @throws SAXException
* @throws ParserConfigurationException
*/
public static void main(String[] args) throws SAXException,
ParserConfigurationException {
String urls[] = new String[] { “http://3g.sina.com.cn/?vt=1&pos=200”,// 新浪wap1.0
http://3g.sina.com.cn/?vt=3&pos=200”,// 新浪wap2.0
http://wap.sohu.com/?nid=1&v=1”,// 搜狐 wap1.0
http://wap.sohu.com/?nid=1&v=3”,// 搜狐 wap2.0
http://info50.3g.qq.com/g/s?aid=index&g_ut=1”,// 手机腾讯网wap1.0
http://info50.3g.qq.com/g/s?aid=index&g_ut=2”, // 手机腾讯网wap2.0
};
for (int i = 0; i < urls.length; i++) {
try {
String urlStr = urls[i];
String xml = downloadUrl(urlStr, null, “UTF-8”);
// System.out.println(xml);
validateWap(xml);
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println(“Over”);
}

/**
* 通过dtd校验wap2.0页面内容,如果抛出异常则说明页面内容有错
*
* @param xml
* @throws ParserConfigurationException
* @throws SAXException
* @throws IOException
*/
public static void validateWap(String xml)
throws ParserConfigurationException, SAXException, IOException {
// //xml = setDTDforWap20(xml);
// //System.out.println(xml);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(true);
DocumentBuilder db = dbf.newDocumentBuilder();
db.setEntityResolver(new LocalEntityResolver());
Document doc = db.parse(new InputSource(new StringReader(xml)));
System.out.println(doc.getFirstChild());
}

public static String downloadUrl(String urlStr, String referer,
String encoding) throws Exception {
String line = “”;
StringBuilder sb = new StringBuilder();
HttpURLConnection httpConn = null;
try {
URL url = new URL(urlStr);
System.out.println(urlStr);
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
“proxy.lizongbo.com”, 8080));
proxy = Proxy.NO_PROXY;
httpConn = (HttpURLConnection) url.openConnection(proxy);
httpConn.setRequestProperty(“User-Agent”, “Nokia”);
httpConn.setDoInput(true);
httpConn.setDoOutput(true);
httpConn.setRequestMethod(“GET”);
if (referer != null) {
httpConn.setRequestProperty(“Referer”, referer);
}
httpConn.setConnectTimeout(1000);
BufferedReader in = null;
if (httpConn.getResponseCode() != 200) {
System.err.println(“error:” + httpConn.getResponseMessage());
in = new BufferedReader(new InputStreamReader(
httpConn.getErrorStream(), “UTF-8”));
} else {
in = new BufferedReader(new InputStreamReader(
httpConn.getInputStream(), “UTF-8”));
}
while ((line = in.readLine()) != null) {
sb.append(line).append(‘\n’);
}
System.out.println(httpConn.getHeaderFields());
// 关闭连接
httpConn.disconnect();
return sb.toString();
} catch (Exception e) {
// 关闭连接
if (httpConn != null) {
try {
httpConn.disconnect();
} catch (Exception e2) {
// TODO: handle exception
}
}
System.out.println(e.getMessage());
throw e;
}
}
}

[/code]

通过上面的例子,可以看到新浪,搜狐,手机腾讯网的wap1.0都校验ok。
而新浪的wap2.0(3G版)使用的声明不是http://www.wapforum.org/DTD/xhtml-mobile10.dtd,却是:xhtml1-strict.dtd

按xhtml1-strict.DTD校验的出错信息为:
Error: URI=null Line=127: Attribute “width” must be declared for element type “input”.
Error: URI=null Line=127: Attribute “height” must be declared for element type “input”.
Error: URI=null Line=127: The content of element type “form” must match “(p|h1|h2|h3|h4|h5|h6|div|ul|ol|dl|pre|hr|blockquote|address|fieldset|table|noscript|ins|del|script)*”.
Error: URI=null Line=155: The content of element type “form” must match “(p|h1|h2|h3|h4|h5|h6|div|ul|ol|dl|pre|hr|blockquote|address|fieldset|table|noscript|ins|del|script)*”.
Error: URI=null Line=236: Attribute value “gototop” of type ID must be unique within the document.
搜狐的wap2.0(彩版)虽然使用的dtd声明是:http://www.wapforum.org/DTD/xhtml-mobile10.dtd,但是页面内容中却使用xhtml1所定义的元素。
按xhtml-mobile10.dtd校验的出错信息为:
Error: URI=null Line=63: Element type “script” must be declared.
Error: URI=null Line=99: The content of element type “div” must match “(h1|h2|h3|h4|h5|h6|ul|ol|dl|p|div|pre|blockquote|address|hr|table|form|fieldset|br|span|em|strong|dfn|code|samp|kbd|var|cite|abbr|acronym|q|i|b|big|small|a|img|object|input|select|textarea|label)”.
Error: URI=null Line=100: Attribute “name” must be declared for element type “form”.
Error: URI=null Line=100: Attribute “accept-charset” must be declared for element type “form”.
Error: URI=null Line=107: Attribute “onclick” must be declared for element type “a”.
Error: URI=null Line=108: Attribute “onclick” must be declared for element type “a”.
Error: URI=null Line=109: Attribute “onclick” must be declared for element type “a”.
Error: URI=null Line=110: The content of element type “form” must match “(h1|h2|h3|h4|h5|h6|ul|ol|dl|p|div|pre|blockquote|address|hr|table|fieldset)+”.
Error: URI=null Line=112: Element type “font” must be declared.
Error: URI=null Line=112: The content of element type “div” must match “(h1|h2|h3|h4|h5|h6|ul|ol|dl|p|div|pre|blockquote|address|hr|table|form|fieldset|br|span|em|strong|dfn|code|samp|kbd|var|cite|abbr|acronym|q|i|b|big|small|a|img|object|input|select|textarea|label)”.

手机腾讯网的wap2.0使用xhtml-mobile10.dtd进行校验,出错信息最少,只有一条:
Error: URI=null Line=141: The content of element type “form” must match “(h1|h2|h3|h4|h5|h6|ul|ol|dl|p|div|pre|blockquote|address|hr|table|fieldset)+”.

 

 

2011年01月1日

获取Android的Java源代码并在Eclipse中关联查看的最新方法

Filed under: Android,Java,前端开发 — 标签:, , , , , , , , — lizongbo @ 01:59

在Google搜索“Android Eclipse 源代码”得到的结果并不合适,因为Google的Eclipse Android开发插件已经更新到了ADT 8.0.1.相应的lib关联java源代码的方式也变了。
以下是获取Android的Java源代码并在Eclipse中关联的最新操作方法和步骤:
1.首先下载Android的SDK安装文件:http://dl.google.com/android/android-sdk_r08-windows.zip
然后解压到:E:\Java\android\android-sdk-windows,运行目录中的SDK Manager.exe,下载好Android不同版本的API包。

2.然后下载或在线安装Eclipse插件ADT,
安装包地址为:http://dl.google.com/android/ADT-8.0.1.zip
在线安装地址:https://dl-ssl.google.com/android/eclipse/
来源:ttp://developer.android.com/sdk/eclipse-adt.html

2.ADT插件安装好之后,下载我已经打包好的Android 2.3(gingerbread)的java源代码压缩包:
下载地址:http://lizongbo.googlecode.com/files/android_gingerbread_javasrc.zip
来源:http://code.google.com/p/lizongbo/downloads/list
下载后复制到E:\Java\android\javasrc。

3.Android的Java源代码压缩包下载好之后,在Eclipse中设置好SDK配置:
操作步骤为:主菜单->Window–>Preferences–>选择Android,SDK Location设置为:E:\Java\android\android-sdk-windows,然后点右下角的Apply来生效。

4.开始进行关联Android的源代码,在Eclipse中新建一个Android工程,选中工程,主菜单 –>Project–>Properties–>选择Android,Project Build Target选中Android 2.3。
然后再点左边的“Java Build Path”,切换到 Libraries 面板,展开 Android2.3 这个lib,点击android.jar的Source attachment,再点Edit.在对话框中点“External File”,选择E:/Java/android/javasrc/android_gingerbread_javasrc.zip,点OK进行确认。这样就把Android的java代码关联好了。

5.在同一个工程中,选中工程,主菜单–>Project–>Properties–>选择 Android,Project Build Target分别选择Android1.5,Android1.6,Android2.01,Android2.1- update1,Android2.2,按上面第四步的操作重复设置关联。
以后在任何Android工程里按住Ctrl用鼠标点击Java类名都可以浏览到对应的java源代码。
Android各个版本对应的源代码为:
Android1.5对应android_cupcake_javasrc.zip
Android1.6对应android_donut_javasrc.zip
Android2.01和Android2.1-update1对应的是android_eclair_javasrc.zip
Android2.2对应android_froyo_javasrc.zip
Android2.3对应android_gingerbread_javasrc.zip

6.在Eclipse配置好源代码关联之后之后的信息会存储在:
E:\lizongbo\workspacenew\.metadata\.plugins\org.eclipse.core.resources\.root\.indexes\properties.index
E:\lizongbo\workspacenew\.metadata\.plugins\org.eclipse.jdt.core\variablesAndContainers.dat

同时记录Android的java源代码压缩包制作方法如下:
1.先在远程的Ubuntu Linux服务器(是Linode VPS)上安装以下组件(JDK1.6已经安装好了):
sudo apt-get install git-core gnupg flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl libncurses5-dev zlib1g-dev
信息来自Android官方:http://source.android.com/source/download.html
2.运行 sudo apt-get install lib32readline5-dev
3.安装Repo脚本:
我懒得配PATH了,于是直接安装到了/usr/local/bin。
root@lizongbo.com:~/bin# cd /usr/local/bin
root@lizongbo.com:/usr/local/bin# ls
geoip-lookup
root@lizongbo.com:/usr/local/bin# curl http://android.git.kernel.org/repo >/usr/local/bin/repo
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
Dload  Upload   Total   Spent    Left  Speed
100 17412  100 17412    0     0  27517      0 –:–:– –:–:– –:–:– 31148
root@lizongbo.com:/usr/local/bin# chmod a+x /usr/local/bin/repo
注意在下载该脚本的时候,可能会遇到服务器出错,下载的内容不对,运行命令的时候会提示错误“syntax error near unexpected token `newline’”。
root@lizongbo.com:/usr/local/bin# repo init -u git://android.git.kernel.org/platform/manifest.git -b cupcake
/usr/local/bin/repo: line 1: syntax error near unexpected token `newline’
/usr/local/bin/repo: line 1: `<!DOCTYPE HTML PUBLIC “-//IETF//DTD HTML 2.0//EN”>’
root@lizongbo.com:/usr/local/bin# more repo
<!DOCTYPE HTML PUBLIC “-//IETF//DTD HTML 2.0//EN”>
<html><head>
<title>500 Internal Server Error</title>
</head><body>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error or
misconfiguration and was unable to complete
your request.</p>
<p>Please contact the server administrator,
webmaster@kernel.org and inform them of the time the error occurred,
and anything you might have done that may have
caused the error.</p>
<p>More information about this error may be available
in the server error log.</p>
</body></html>
从内容看是服务器出错了,因此需要重新下载脚本.
4.建立mydroid目录,按代码分支下载对应版本的Android完整的源代码,比如下载Android2.3的代码:
root@lizongbo.com:~/mydroid# mkdir gingerbread
root@lizongbo.com:~/mydroid# cd gingerbread/
root@lizongbo.com:~/mydroid/gingerbread# repo init -u git://android.git.kernel.org/platform/manifest.git -b gingerbread
root@lizongbo.com:~/mydroid/gingerbread# repo sync
Android1.5的代码分支:
root@lizongbo.com:~/mydroid/cupcake# repo init -u git://android.git.kernel.org/platform/manifest.git -b cupcake
root@lizongbo.com:~/mydroid/cupcake# repo sync
Android1.6的代码分支:
root@lizongbo.com:~/mydroid/donut# repo init -u git://android.git.kernel.org/platform/manifest.git -b donut
root@lizongbo.com:~/mydroid/donut# repo sync
Android2.0.1和2.1的代码分支:
root@lizongbo.com:~/mydroid/eclair# repo init -u git://android.git.kernel.org/platform/manifest.git -b eclair
root@lizongbo.com:~/mydroid/eclair# repo sync
Android2.2的代码分支:
root@lizongbo.com:~/mydroid/froyo# repo init -u git://android.git.kernel.org/platform/manifest.git -b froyo
root@lizongbo.com:~/mydroid/froyo# repo sync

如果遇到代码下载速度太慢,可以指定hosts,hosts配置不住为:
root@lizongbo.com:~/mydroid/gingerbread/.repo/projects# nslookup
> android.git.kernel.org
Server:         72.14.188.5
Address:        72.14.188.5#53
Non-authoritative answer:
android.git.kernel.org  canonical name = android.git.geo.kernel.org.
android.git.geo.kernel.org      canonical name = android.git.us.kernel.org.
Name:   android.git.us.kernel.org
Address: 149.20.20.141
Name:   android.git.us.kernel.org
Address: 204.152.191.45
> exit

root@lizongbo.com:/etc# vi hosts
204.152.191.45 android.git.us.kernel.org
204.152.191.45 android.git.kernel.org

网上有文章介绍使用提取java文件并打包的pytho脚本可以生成源代码包,参考:
http://android.opensourceror.org/2010/01/18/android-source/
http://blog.michael-forster.de/2008/12/view-android-source-code-in-eclipse.html
Python下载地址:http://www.python.org/ftp/python/2.6.6/python-2.6.6.msi
但是在Android2.2和Android2.3的代码里,Android写一了一些mock的类,比如android.webkit.WebView,使用python脚本打包的话,会把mock的源代码打进去,而不是真正的源代码,
因此我根据python脚本写了个java程序来提取java文件过滤冗余的java代码并打包。
生成的java源代码压缩:android_cupcake_javasrc.zip,android_donut_javasrc.zip,android_eclair_javasrc.zip,android_froyo_javasrc.zip,android_gingerbread_javasrc.zip
目前在code.google.com上传了android_gingerbread_javasrc.zip,欢迎下载。

以下是各版本的Android java source 下载地址:

Android2.3: http://lizongbo.googlecode.com/files/android_gingerbread_javasrc.zip

Android1.5: http://lizongbo.googlecode.com/files/android_cupcake_javasrc.zip
Android1.6: http://lizongbo.googlecode.com/files/android_donut_javasrc.zip
Android2.1: http://lizongbo.googlecode.com/files/android_eclair_javasrc.zip
Android2.2: http://lizongbo.googlecode.com/files/android_froyo_javasrc.zip

新年快乐!

2010年12月29日

手机上常见的安装文件名后缀和mime类型

Filed under: Android,Java — 标签:, , , , , , , , , , , — lizongbo @ 00:43

手机上常见安装文件名后缀和mime类型
kjava是最通用的平台,有些手机只支持kjava,j2me的安装文件名以jar和jad结尾。
Android平台的软件后缀名是apk
例如手机QQ1.0(Android)Beta3Build0077的安装文件是:MobileQQ1.0(Android)Beta3Build0077.apk
如果安装了Java虚拟机的话,也可以安装文件名以jar和jad结尾的软件。
塞班(Symbian)的S60V3和S60v5平台支持的文件名后缀有:sis,sisx,jar,jad,wgz。
例如:手机QQ2010(S60V3)Beta4Build1186的安装文件名为:QQ2010(S60V3)Beta4Build1186.sisx
塞班(Symbian)S40平台只支持kjava因此安装文件名也是以jar和jad结尾。
塞班(Symbian)S60V2平台通常也支持kjava,也支持sis格式的安装文件,因此支持的格式一共有sis,jar,jad。
Symbian3是塞班新出的平台支持的文件名后缀有jar,jad,sisx和sis。
黑莓(BlackBerry)平台支持的文件名后缀有jar,jad,cod。
Plam webOS支持的安装文件名后缀有jar,jad,prc,ipk。
MTK平台的手机分支持java和不支持java两种情况,一般支持的安装文件名后缀有jar,jad,mrp。
斯凯平台是MTK平台上的中间件,支持的文件名后缀为:mrp
iPhone操作系统支持的按成程序文件名后缀为:pxl,ipa,deb。
Windows Mobile平台支持的文件名后缀有cab,jar,jad,exe。
例如手机QQ2008(Pocket PC)正式版 Build0093的安装文件名为:PPCQQ2008_Build093.CAB
下面是各种文件名后缀在nginx的mime.types中的配置:
text/vnd.sun.j2me.app-descriptor      jad;
application/java-archive              jar war ear;
application/x-java-archive-diff       jardiff;
application/vnd.android.package-archive apk;
application/vnd.ms-cab-compressed              cab;
application/octet-stream              bin exe dll;
application/vnd.symbian.install       sis;
x-epoc/x-sisx-app                     sisx;
application/iphone                    pxl ipa;
application/vnd.palm                  prc pdb;
application/vnd.webos.ipk             ipk;
application/vnd.rim.cod               cod;
application/mrp                       mrp;
x-nokia-widget                        wgz;
application/octet-stream              deb;

下面的一些mime是关于图片和视频的,列在这里备忘:
video/3gpp                            3gpp 3gp;
image/jpeg                            jpeg jpg;
image/png                             png;
image/gif                             gif;

相关参考链接:http://nds.nokia.com/uaprof/NN81-1r100.xml
APK文件格式说明:http://en.wikipedia.org/wiki/APK_%28file_format%29
sis文件格式:http://zh.wikipedia.org/zh/SIS_%28%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F%29
jad文件格式: http://en.wikipedia.org/wiki/JAD_%28file_format%29
手机QQ下载:http://msoft.qq.com/d/mqq/

Older Posts »

Powered by WordPress