【发布时间】:2014-11-13 16:41:14
【问题描述】:
Jsoup 在 kitkat 上的解析速度似乎比在 kitkat 之前的任何东西上都要慢得多。我不确定它是否是 ART 运行时,但在对解析方法运行速度测试后发现它慢了大约 5 倍,我不知道为什么..
我的这部分代码在异步任务的 doInBackground 中运行。
JsoupParser parser = new JsoupParser();
parser.setPath(String.valueOf(application.getCacheDir()));
Collection<Section> allSections = eguide.getSectionMap().values();
for (Section section : allSections) {
parser.createNewAssetList();
parser.setContent(section.color, section.name, section.text, section.slug);
if (!TextUtils.isEmpty(section.text)) {
section.text = parser.setWebViewStringContent();
section.assets = parser.getAssets();
for (Asset asset : section.assets)
asset.heading = section.heading;
}
}
我很久以前写过这个,它可能效率不高,但它设置了解析器,加载了一个 Section 对象列表,对于每个对象,它都会将 html 提取表和图像解析为一个不同对象的列表,这些对象返回到原始部分对象..
这是我的解析器类。
public class JsoupParser{
private List<Asset> assets;
private int assetCount;
private String slug,name,color,path;
private Document doc;
public JsoupParser() {
assetCount = 0;
assets = new ArrayList<Asset>();
}
public void setPath(String path) {
this.path = path;
}
public void setContent(String color, String name, String text, String slug){
this.color = color;
this.name = name;
this.slug = slug;
doc = Jsoup.parse(text);
}
public void createNewAssetList(){
assetCount = 0;
assets = new ArrayList<Asset>();
}
public String setWebViewStringContent() {
addScriptsAndDivTags();
//parse images
Elements images = doc.select("img[src]");
parseImages(images);
//parse tables
Elements tableTags = doc.select("table");
parseTables(tableTags);
return doc.toString();
}
private void addScriptsAndDivTags() {
Element bodyReference = doc.select("body").first(); //grab head and body ref's
Element headReference = doc.select("head").first();
Element new_body = doc.createElement("body");
//wrap content in extra div and add accodrion tag
bodyReference.tagName("div");
bodyReference.attr("id", "accordion");
new_body.appendChild(bodyReference);
headReference.after(new_body);
}
private void parseTables(Elements tableTags) {
if (tableTags != null) {
int count = 1;
for (Element table : tableTags) {
Asset item = new Asset();
item.setContent(table.toString());
item.setColor(color);
item.id = (int) Math.ceil(Math.random() * 10000);
item.isAsset=1;
item.keywords = table.attr("keywords");
String linkHref = table.attr("table_name");
item.slug = "t_" + slug + " " + count ;
if(!TextUtils.isEmpty(linkHref)){
item.name = linkHref;
}
else{
item.name ="Table-" + (assetCount + 1) + " in " + name;
}
// replace tables
String inline = table.attr("inline");
String button = ("<p>Dummy Button</p>");
if(!TextUtils.isEmpty(inline)&& inline.contentEquals("false") || TextUtils.isEmpty(inline) )
{
table.replaceWith(new DataNode(button, ""));
}
else{
Element div = doc.createElement("div");
div.attr("class","inlineTableWrapper");
div.attr("onclick", "window.location ='table://"+item.slug+"';");
table.replaceWith(div);
div.appendChild(table);
}
assets.add(item);
assetCount++;
count++;
}
}
}
private void parseImages(Elements images) {
for (Element image : images) {
Asset item = new Asset();
String slug = image.attr("src");
//remove first forward slash from slug to account for img:// protocol in image linking
if(slug.charAt(0)=='/')
slug = slug.substring(1,slug.length());
image.attr("src", path +"/images/" + slug.substring(slug.lastIndexOf("/")+1, slug.length()));
image.attr("style", "px; border:1px solid #000000;");
String image_name = image.attr("image_name");
if(!TextUtils.isEmpty(image_name)){
item.name = image_name;
}
else{
item.name ="Image " + (assetCount + 1) + " in " + name;
}
// replace tables
String inline = image.attr("inline");
String button = ("<p>Dummy Button</p>");
item.setContent(image.toString()+"<br/><br/><br/><br/>");
if(!TextUtils.isEmpty(inline)&& inline.contentEquals("false"))
{
image.replaceWith(new DataNode(button, ""));
}
else{
image.attr("onclick", "window.location ='img://"+slug+"';");
}
item.keywords = image.attr("keywords");
item.setColor(color);
item.id = (int) Math.ceil(Math.random() * 10000);
item.slug = slug;
item.isAsset =2;
assets.add(item);
assetCount++;
}
}
public String getName() {
return name;
}
public List<Asset> getAssets() {
return assets;
}
}
同样,它可能效率不高,但到目前为止我一直无法找出为什么它会对 kitkat 造成如此大的影响。任何信息将不胜感激。 谢谢!
【问题讨论】:
-
你有没有发现更多关于 KitKat 下的 jsoup 速度问题(现在还有 Lollipop)?我在我的应用程序中使用 jsoup 并发现我所做的所有 HTML 页面解析在 Android 4.3、4.2.2 的旧设备上的运行速度比在 KitKat 和 Lollipop 的相对较新的设备上快 5 到 10 倍。摸不着头脑……顺便说一句,我在 ART 和 Dalvik 之间切换了一个 KitKat 设备,jsoup 解析速度没有区别。
-
@gregko 遗憾的是没有。这是我从未设法解决的少数几个问题之一。现在我得到了生产代码,在旧设备上解析比在新设备上更快。每次看到我都咬着嘴唇。如果您找到解决方案,请传递。 ;)
-
我正在解决这个问题,我已经在我的产品中找到了一个我能够修复的地方。将尝试识别更多,希望可以在 jsoup 代码中引入一些东西。另请参阅我在 GitHub 上与 jsoup 作者的讨论:github.com/jhy/jsoup/issues/383#issuecomment-88880188
标签: android performance parsing jsoup android-4.4-kitkat