用Eclipse開(kāi)發(fā)iPhone Web 應(yīng)用程序
清單 4. 輸出詳細(xì)信息頁(yè)面的 Doclet 代碼
private void printDetail(PrintStream p, ProgramElementDoc doc,
String id, String name) {
divHeader(p, id, name, "panel");
textHeader(p, null);
textRow(p, getSignature(doc));
textRow(p, getCommentText(doc.commentText()));
textFooter(p);
if (doc instanceof ExecutableMemberDoc) {
printMethodDetail(p, (ExecutableMemberDoc) doc);
}
divFooter(p);
}
private void printMethodDetail(PrintStream p, ExecutableMemberDoc field) {
if (field.parameters().length > 0) {
textHeader(p, "Parameters");
for (int i=0; i<field.paramTags().length; i++) {
textRow(p, "<b>" + field.parameters()[i].typeName() + " "
+ field.paramTags()[i].parameterName()
+ "</b>: "
+ getCommentText(field.paramTags()[i].parameterComment()));
}
textFooter(p);
}
if (field.throwsTags().length > 0) {
textHeader(p, "Throws");
for (int i=0; i<field.throwsTags().length; i++) {
textRow(p, "<b>" + field.throwsTags()[i].exceptionName()
+ "</b>: "
+ getCommentText(field.throwsTags()[i].exceptionComment()));
}
textFooter(p);
}
}
代碼是通用的,這樣 printDetail() 將處理類(lèi)描述、字段、構(gòu)造函數(shù)和方法的輸出。后兩種類(lèi)型是 ExecutableMemberDoc 的子類(lèi),因此打印關(guān)于其參數(shù)和已拋出異常的附加信息。
Aptana 的 iPhone Preview 模式將幫助調(diào)試輸出文件。在每次迭代后,您可以快速單擊該應(yīng)用程序查找已設(shè)計(jì)界面中的不一致性。但是,使用 Preview 模式可以掩蓋性能問(wèn)題:現(xiàn)代計(jì)算機(jī)的運(yùn)行速度比 iPhone 的 620-MHz ARM 處理器快三至五倍。此外,用戶經(jīng)常通過(guò)速度慢的蜂窩網(wǎng)絡(luò)下載頁(yè)面,因此必須用實(shí)際 iPhone 運(yùn)行您的應(yīng)用程序。
性能問(wèn)題
當(dāng)我在 iPhone 中測(cè)試查看 iDoc 時(shí),我發(fā)現(xiàn)輸出一個(gè)大型 HTML 文件將導(dǎo)致跳幀和性能下降。要解決此問(wèn)題,創(chuàng)建一個(gè)用于導(dǎo)航包名/類(lèi)名的主文件,然后為帶有注釋和方法細(xì)節(jié)的每個(gè)類(lèi)創(chuàng)建獨(dú)立文件(參見(jiàn)清單 5)。雖然此過(guò)程將生成大量文件,但是各個(gè)文件大小都非常小,并且應(yīng)用程序運(yùn)行得十分流暢。
清單 5. Doclet 代碼將迭代每個(gè)包,然后為每個(gè)類(lèi)創(chuàng)建文件
out = new FileOutputStream(index);
p = new PrintStream(out);
printHeader(p);
PackageDoc[] packages = root.specifiedPackages();
Arrays.sort(packages);
printPackages(p, packages);
for (int i=0; i<packages.length; i++) {
printPackageDetail(p, packages[i]);
}
for (int i=0; i<packages.length; i++) {
ClassDoc[] classes = packages[i].allClasses();
Arrays.sort(classes);
for (int j=0; j<classes.length; j++) {
// Creating a separate file for each class.
PrintStream p2 = new PrintStream(new FileOutputStream(getFilename(classes[j])));
printClassDetail(p2, classes[j]);
p2.close();
}
}
printFooter(p);
p.close();
運(yùn)行 iDoc
在經(jīng)過(guò)該性能增強(qiáng)之后,就能運(yùn)行 iDoc 了。為 OpenJDK 中的 51 個(gè) java.* 和 javax.* 包(表示 1,304 個(gè)類(lèi))生成 Javadoc,然后把所有內(nèi)容上傳到 Web 服務(wù)器中。這包括超過(guò) 16 MB 的文件,但是主要導(dǎo)航頁(yè)面只有 112 KB,并且每個(gè)單獨(dú)類(lèi)的詳細(xì)信息頁(yè)面平均為 13 KB。即使在使用 EDGE 網(wǎng)絡(luò)時(shí),應(yīng)用程序也能夠快速響應(yīng)。如果您已經(jīng)擁有了 iPhone,請(qǐng)?jiān)L問(wèn) iDoc 站點(diǎn)(請(qǐng)參閱 參考資料)并嘗試使用,也可以下載 iDoc 來(lái)為您自己的代碼庫(kù)生成特定于 iPhone 的 Javadoc。圖 11 顯示了最終的應(yīng)用程序。
圖 11. 用于 iPhone 的全部 51 個(gè)包的 Javadoc
可能對(duì) iDoc 進(jìn)行的擴(kuò)展包括支持顯示 Java 5 泛型,以及更智能地捕捉 Javadoc 注釋內(nèi)的標(biāo)記來(lái)實(shí)現(xiàn)頁(yè)面之間的鏈接。如果您有興趣添加 iDoc 的功能,則可以下載完整的源代碼.
iPhone 開(kāi)發(fā)的前景
2007 年 10 月,Steve Jobs 宣稱(chēng) Apple 將于 2008 年 2 月發(fā)布 iPhone SDK。詳細(xì)信息很少,因?yàn)檫@是在 2007 年 12 月編寫(xiě)的,但是 SDK 將允許您在不需要使用 Safari 的情況下創(chuàng)建能夠在 iPhone 上本機(jī)運(yùn)行的應(yīng)用程序。給定 iPhone 底層架構(gòu)之后,開(kāi)發(fā)平臺(tái)很可能是類(lèi)似于 Mac OS X 的 Cocoa 和 Objective-C。Apple 主管人員的最新評(píng)論暗示第三方應(yīng)用程序?qū)⑿枰邮苣撤N類(lèi)型的認(rèn)證過(guò)程。
通過(guò)在本機(jī)運(yùn)行,需要高級(jí)動(dòng)畫(huà)、圖形和網(wǎng)絡(luò)訪問(wèn)的應(yīng)用程序?qū)闹蝎@益。不過(guò),即使在發(fā)布了 SDK 之后,iPhone 的 Web 開(kāi)發(fā)仍會(huì)是一個(gè)吸引人的主題。Web 應(yīng)用程序很容易創(chuàng)建和部署。諸如 Aptana 和 iUi 之類(lèi)的工具簡(jiǎn)化了開(kāi)發(fā),并且能夠快速創(chuàng)建 Web 應(yīng)用程序。正如 iDoc 所展示的,沒(méi)有必要等待 SDK 的發(fā)布:使用現(xiàn)有的工具,您可以創(chuàng)建具有本機(jī)界面外觀的全功能 iPhone Web 應(yīng)用程序。
評(píng)論