Android 解析xml时使用progressDialog
这是我在stackoverflow上的第一篇文章,我是Android新手。我已经在论坛上搜索了一个类似的问题,发现了这个问题:。 但不幸的是,这对我没有帮助。 我的应用程序必须在日历中注册事件。 我实现的第一件事是推进xml文件的下载。您可以在附加的代码中看到这一点。 之后,我希望progressDialog重置并开始跟踪解析的进度。如果可以用一个新的setMessage()和一个百分比值来完成,那就太好了。 解析后,数据用于在日历中注册事件,同样使用相同的progressDialog 但首先我想知道如何跟踪解析的进度。如果你有一些想法就好了。 多谢各位Android 解析xml时使用progressDialog,android,xml-parsing,android-asynctask,progressdialog,Android,Xml Parsing,Android Asynctask,Progressdialog,这是我在stackoverflow上的第一篇文章,我是Android新手。我已经在论坛上搜索了一个类似的问题,发现了这个问题:。 但不幸的是,这对我没有帮助。 我的应用程序必须在日历中注册事件。 我实现的第一件事是推进xml文件的下载。您可以在附加的代码中看到这一点。 之后,我希望progressDialog重置并开始跟踪解析的进度。如果可以用一个新的setMessage()和一个百分比值来完成,那就太好了。 解析后,数据用于在日历中注册事件,同样使用相同的progressDialog 但首先我
public class AddCoursesToCalendar extends Activity {
public static final int progress_bar_type = 0;
ArrayList<String> selectedCourses;
public ProgressDialog progressDialog;
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_add_courses_to_calendar);
if (bundle != null) {
selectedCourses = bundle.getStringArrayList("selectedCourses");
}
new GetDataTask().execute();
}
private Boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni != null && ni.isConnected())
return true;
return false;
}
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case progress_bar_type:
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Downloading file. Please wait...");
progressDialog.setIndeterminate(false);
progressDialog.setMax(100);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(true);
progressDialog.show();
return progressDialog;
default:
return null;
}
}
public class GetDataTask extends AsyncTask<String, String, Integer> {
private static final String URL = "http://10.0.2.2/WIN2.xml";
private static final String KEY_ITEM = "Item";
private static final String KEY_DAUER = "Duration";
private static final String KEY_ENDE = "End";
private static final String KEY_SEMESTER_DOZENT = "Location";
private static final String KEY_RAUMMITSTOCKWERK = "Organizer";
private static final String KEY_START = "Start";
private static final String KEY_VERANSTALTUNGSNAME = "Subject";
@Override
protected void onPreExecute() {
super.onPreExecute();
onCreateDialog(progress_bar_type);
}
@Override
protected Integer doInBackground(String... params) {
if (isOnline()) {
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(URL, this);
long id = 0;
Document doc = parser.getDomElement(xml, this);
NodeList nl = doc.getElementsByTagName(KEY_ITEM);
for (int i = 0; i < nl.getLength(); i++){
Element e = (Element) nl.item(i);
for (String s : selectedCourses) {
if (parser.getValue(e, KEY_VERANSTALTUNGSNAME)
.contains(s)) {
String dozent = null;
int spaceIndex = parser.getValue(e,
KEY_SEMESTER_DOZENT).indexOf(" ");
int lastIndex = parser.getValue(e,
KEY_SEMESTER_DOZENT).length();
if (spaceIndex != -1) {
dozent = parser
.getValue(e, KEY_SEMESTER_DOZENT)
.substring(spaceIndex, lastIndex);
}
addEvent(
parser.getValue(e, KEY_VERANSTALTUNGSNAME),
parser.getValue(e, KEY_START),
parser.getValue(e, KEY_ENDE),
parser.getValue(e, KEY_DAUER),
dozent,
parser.getValue(e, KEY_RAUMMITSTOCKWERK),
id);
} id++;
}
}
} else {
Toast.makeText(AddCoursesToCalendar.this, "No Connection..",
Toast.LENGTH_LONG).show();
}
return 1;
}
public void doProgress(String value){
publishProgress(value);
}
@Override
protected void onPostExecute(Integer result) {
progressDialog.dismiss();
super.onPostExecute(result);
}
protected void onProgressUpdate(String... progress) {
progressDialog.setProgress(Integer.parseInt(progress[0]));
}
protected void addEvent(String title, String start, String end,
String duration, String organizer, String location, long id) {
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
long startInMillis = 0, endInMillis = 0;
Date startDate, endDate;
try {
startDate = format.parse(start);
endDate = format.parse(end);
startInMillis = startDate.getTime();
endInMillis = endDate.getTime();
} catch (ParseException e1) {
e1.printStackTrace();
}
TimeZone timeZone = TimeZone.getDefault();
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.EVENT_TIMEZONE, timeZone.getID());
values.put(CalendarContract.Events.DTSTART, startInMillis);
values.put(CalendarContract.Events.DTEND, endInMillis);
values.put(CalendarContract.Events.TITLE, title);
values.put(CalendarContract.Events.EVENT_LOCATION, "Location: " + location);
values.put(CalendarContract.Events.CALENDAR_ID, 1);
Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);
ContentUris.withAppendedId(uri, id);
}
}
}
我希望我的第一篇文章的风格是好的,如果不是请告诉我。提前谢谢我假设XML非常大,并且解析至少需要30秒。否则,帮你自己一个忙,只需显示一个不确定的指标;) 此外,为了简化代码,您可能希望使用而不是功能齐全的
HttpClient
,并切换到简单的GET
(因为您不发送任何参数,我想知道为什么您的服务器需要POST
)
假设该文件非常大(当然,对于手机而言),则必须考虑内存使用情况,并且您将从DOM切换到处理XML。SAX在扫描流时为您提供了一个基于事件的接口,因此您甚至不必在开始处理之前将整个文件加载到内存中。请记住,这是一个大文件,我们不想耗尽内存
使用SAX,我们可以在下载文件时对其进行解析,因此在计算总时间和剩余时间时,我们可以关闭网络延迟。此时,进度可通过当前项目/总计进行近似计算。您可以更新内部计数器以跟踪当前项目,但现在的问题是如何计算总数。你可以用
内容长度
HTTP头或一个前导(在这个代码段中称为
):
291
...
福
酒吧
...
AsyncTask
部分非常简单:您可以在doInBackground()
中使用,然后它将在UI线程上调用onProgressUpdate()
。在这个方法中,您将看到对话框的一部分
最后几点注意事项:当屏幕旋转时(假定为默认配置),您的活动将被销毁,然后重新创建。请注意,通过Activity.showDialog
显示的对话框由系统自动重新创建,但旧的AsyncTask
仍在运行,它可能会保留对旧的(现在可能已销毁但未垃圾回收)活动和旧对话框的引用。您必须自己处理这个问题,有(包括加载程序框架)
我希望您现在明白,这项任务并不像听起来那么简单,因此我的建议是仔细检查业务需求,并提出最简单、更可靠的解决方案——毕竟,下载XML并显示进度对话框不是应用程序的主要任务;) 您可以使用asynctask来实现所需的结果。。这还不错,但如果你能想出一个一般性的问题就更好了。。比如“如何跟踪xml文件的解析并显示进度?”之类的…:)@拉古南丹:谢谢你的帖子,我已经在使用asynctask了。我想知道如何检查parsing onPreExecute()的进度,您可能希望调用showDialog(DLG_progress)而不是onCreateDialog()。
public class XMLParser {
public String getXmlFromUrl(String url, AddCoursesToCalendar.GetDataTask task) {
String xml = null;
try {
int count;
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
long lenghtOfFile = httpEntity.getContentLength();
byte data[] = new byte[1024];
long total = 0;
while ((count = httpEntity.getContent().read(data)) != -1) {
total += count;
task.doProgress(""+(int)((total*100)/lenghtOfFile));
}
xml = EntityUtils.toString(httpEntity, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return xml;
}
public Document getDomElement(String xml, AddCoursesToCalendar.GetDataTask task) {
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
StringReader reader = new StringReader(xml);
is.setCharacterStream(reader);
doc = db.parse(is);
} catch (ParserConfigurationException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (SAXException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (IOException e) {
Log.e("Error: ", e.getMessage());
return null;
}
return doc;
}
public String getValue(Element item, String str) {
NodeList n = item.getElementsByTagName(str);
return this.getElementValue(n.item(0));
}
public final String getElementValue(Node elem) {
Node child;
if (elem != null) {
if (elem.hasChildNodes()) {
for (child = elem.getFirstChild(); child != null; child = child
.getNextSibling()) {
if (child.getNodeType() == Node.TEXT_NODE) {
return child.getNodeValue();
}
}
}
}
return "";
}
<root>
<manifest>
<total>291</total>
</manifest>
...
<item id="foobar1">
<foo>Foo</foo>
<bar>Bar</bar>
</item>
...
</root>