在我的项目中,我将使用大量的XML数据:
<person>
<name>Alex</name>
<data1>data1</data1>
<data2>data2</data2>
<data3>data3</data3>
</person>
<person>
<name>paul</name>
<data1>data1</data1>
<data2>data2</data2>
<data3>data3</data3>
</person>
这些XML文件有600多个托管。我用片段调用他们的网站并加载它们需要很长时间并抛出: “I / Choreographer:跳过47帧!应用程序可能在其主线程上做了太多工作。” 我已经知道如何通过启动另一个线程来解决这个问题。打开页面仍需要几秒钟,我实施的“关键字搜索”会导致Android监视器丢失 “我/艺术:背景部分并发标记扫描GC释放83556(6MB)AllocSpace对象,834(16MB)LOS对象,45%免费,19MB / 35MB,暂停296us总计124.540ms” 像每第3次一样。我已经读到这是正常的事情,但应该避免。
由于我还不熟悉Android,我想知道我是否做得对,或者我是否可以使用数据库更好地处理数据。
private static String getValue(String tag, Element element) {
NodeList nodeList = element.getElementsByTagName(tag).item(0).getChildNodes();
Node node = nodeList.item(0);
return node.getNodeValue();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
//return inflater.inflate(R.layout.fragment_coffee_pref, container, false);
final View view = inflater.inflate(R.layout.fragment_coffee_pref, container, false);
try {
// get XML file
AssetManager assetManager = getActivity().getAssets();
if(Locale.getDefault().getLanguage().equals("de")){
is = assetManager.open("coffee_pref_DE.xml");
}else{
is = assetManager.open("coffee_pref.xml");
}
//init XML parser
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(is);
Element element=doc.getDocumentElement();
element.normalize();
// init table
LinearLayout CPcontainer = (LinearLayout) view.findViewById(R.id.CPcontainer);
TableRow.LayoutParams w50Layout = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT,0.50f);
TableRow.LayoutParams w100Layout = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT,1.0f);
//paramsExample.setMargins(2, 2, 2, 2); // (left, top, right, bottom);
// go throught XML List and insert rows for each entry
NodeList nList = doc.getElementsByTagName("person");
for (int i=0; i<nList.getLength(); i++) {
Node node = nList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
TableLayout tableLayout = new TableLayout(getActivity());
tableLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));// assuming the parent view is a LinearLayout
TableRow row1= new TableRow(getActivity());
TableRow row2= new TableRow(getActivity());
TableRow row3= new TableRow(getActivity());
TableRow row4= new TableRow(getActivity());
TableRow.LayoutParams lp = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT);
row1.setLayoutParams(lp);
row2.setLayoutParams(lp);
row3.setLayoutParams(lp);
row4.setLayoutParams(lp);
Element element2 = (Element) node;
// row 1
TextView tvName = new TextView(getActivity());
tvName.setLayoutParams(w100Layout);
tvName.setText(Html.fromHtml("<a href=\""+getValue("link", element2)+"\">"+getValue("name", element2)+"</a>"));
tvName.setMovementMethod(LinkMovementMethod.getInstance());
tvName.setBackgroundResource(R.drawable.head_shape);
tvName.setPadding(30, 20, 30, 20); // (left, top, right, bottom);
row1.addView(tvName);
tableLayout.addView(row1);
// row 2
TextView tvData1 = new TextView(getActivity());
tvData1.setLayoutParams(w50Layout);
tvData1.setText(getValue("data1", element2));
tvData1.setBackgroundResource(R.drawable.cell_shape);
tvData1.setPadding(30, 20, 30, 20); // (left, top, right, bottom);
TextView textData1 = new TextView(getActivity());
textData1.setText(R.string.tableData1);
textData1.setLayoutParams(w50Layout);
//textData1.setTypeface(null, Typeface.BOLD);
textData1.setBackgroundResource(R.drawable.cell_shape);
textData1.setPadding(30, 20, 30, 20); // (left, top, right, bottom);
row2.addView(textData1);
row2.addView(tvData1);
tableLayout.addView(row2);
// row3
TextView tvData2 = new TextView(getActivity());
tvData2.setLayoutParams(w50Layout);
tvData2.setText(getValue("data2", element2));
tvData2.setBackgroundResource(R.drawable.cell_shape);
tvData2.setPadding(30, 20, 30, 20); // (left, top, right, bottom);
TextView textData2 = new TextView(getActivity());
textData2.setText(R.string.tableData2);
textData2.setLayoutParams(w50Layout);
//textData2.setTypeface(null, Typeface.BOLD);
textData2.setBackgroundResource(R.drawable.cell_shape);
textData2.setPadding(30, 20, 30, 20); // (left, top, right, bottom);
row3.addView(textData2);
row3.addView(tvData2);
tableLayout.addView(row3);
// row 4
TextView tvData3 = new TextView(getActivity());
tvData3.setLayoutParams(w50Layout);
tvData3.setText(getValue("sugar", element2));
tvData3.setBackgroundResource(R.drawable.cell_shape);
tvData3.setPadding(30, 20, 30, 20); // (left, top, right, bottom);
TextView textData3 = new TextView(getActivity());
textData3.setText(R.string.tableData3);
textData3.setLayoutParams(w50Layout);
//textData3.setTypeface(null, Typeface.BOLD);
textData3.setBackgroundResource(R.drawable.cell_shape);
textData3.setPadding(30, 20, 30, 20); // (left, top, right, bottom);
row4.addView(textData3);
row4.addView(tvData3);
tableLayout.addView(row4);
// add table to layout
CPcontainer.addView(tableLayout);
}
}
} catch (Exception e) {e.printStackTrace();}
searchforName = (EditText) view.findViewById(R.id.searchForName);
searchforName.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
String searchedName = searchforName.getText().toString().toLowerCase();
LinearLayout CPcontainer = (LinearLayout) view.findViewById(R.id.CPcontainer);
for (int i = 1, j = CPcontainer.getChildCount(); i < j; i++) {
View view2 = CPcontainer.getChildAt(i);
if(view2 instanceof TableLayout) {
TableLayout table2 = (TableLayout) view2;
TableRow row2 = (TableRow) table2.getChildAt(0);
if (!TextUtils.isEmpty(searchedName)) {
TextView searchableName = (TextView) row2.getChildAt(0);
String sName = Html.fromHtml(searchableName.getText().toString()).toString();
if (sName.startsWith(searchedName) || sName.equals(searchedName)) {
//if (sName.toLowerCase().contains(searchedName)) {
table2.setVisibility(View.VISIBLE);
} else {
table2.setVisibility(View.GONE);
}
} else {
table2.setVisibility(View.VISIBLE);
}
}
}
}
});
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
return view;
}
此外,由于我在名称TextView中实现了一个HTML链接,我不能再搜索它了,我无法弄清楚如何绕过它。
String sName = Html.fromHtml(searchableName.getText().toString()).toString();
我会感谢每一个关于我的问题的帮助或信息!
答案 0 :(得分:0)
对于大型文档,XML解析通常很讨厌 - 你创建了很多小对象,它会在垃圾收集器中造成很大的破坏。试图最小化对象创建的库可以提供帮助,但它总是很糟糕。
所以我不会真的担心GC警告。最后,你不会去OOM或导致泄密。对于chorographer警告 - 在解析大型文档时,在另一个线程或AsyncTask上执行此操作。然后主UI线程可以继续正常处理。完成解析后,将事件发送到主线程以进行任何UI更改。
答案 1 :(得分:0)
您很可能有一个缓慢的DocumentBuilder来解析您的XML。如果您有这么多条目,您有几个选择:
查看是否可以通过阻止验证等来提高构建器性能(请将此链接视为一种方法:https://jdevel.wordpress.com/2011/03/28/java-documentbuilder-xml-parsing-is-very-slow/)。我建议在代码中包装它以启用/禁用它以进行调试。
调查DOM和SAX(What is the difference between SAX and DOM?)之间的差异 - 您可能希望并能够使用SAX方法。
查看更改数据的组织方式和/或将其拆分为不同的文件。
最后,XML已经占据了它的位置但是如果性能是最高优先级,那么你应该使用不同的文件格式,那么如果你构建一个自定义解决方案,可以根据你的需要优化文档结构/传输/解析(通常这只适用于非常强烈/高级的工作,如果可能的话应该避免。)