我正在尝试提取和解析我正在摆弄的XML文件。我试图将其拉下来并在列表视图中显示它。
我无法弄清楚为什么它没有返回结果?
请参阅以下活动:
MainActivity.java
package com.ryan.bobxmlpullproject;
import java.io.FileNotFoundException;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
public class MainActivity extends Activity {
private SitesAdapter mAdapter;
private ListView sitesList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("StackSites", "OnCreate()");
setContentView(R.layout.activity_main);
//Get reference to our ListView
sitesList = (ListView)findViewById(R.id.sitesList);
//Set the click listener to launch the browser when a row is clicked.
sitesList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View v, int pos,long id) {
String url = mAdapter.getItem(pos).getLink();
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
/*
* If network is available download the xml from the Internet.
* If not then try to use the local file from last time.
*/
if(isNetworkAvailable()){
Log.i("StackSites", "starting download Task");
SitesDownloadTask download = new SitesDownloadTask();
download.execute();
}else{
mAdapter = new SitesAdapter(getApplicationContext(), -1, SitesXmlPullParser.getStackSitesFromFile(MainActivity.this));
sitesList.setAdapter(mAdapter);
}
}
//Helper method to determine if Internet connection is available.
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
/*
* AsyncTask that will download the xml file for us and store it locally.
* After the download is done we'll parse the local file.
*/
private class SitesDownloadTask extends AsyncTask<Void, Void, Void>{
@Override
protected Void doInBackground(Void... arg0) {
//Download the file
try {
Downloader.DownloadFromUrl("https://www.dropbox.com/s/w463wkx85dlbtbx/iPhoneSearch.xml", openFileOutput("StackSites.xml", Context.MODE_PRIVATE));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result){
//setup our Adapter and set it to the ListView.
mAdapter = new SitesAdapter(MainActivity.this, -1, SitesXmlPullParser.getStackSitesFromFile(MainActivity.this));
sitesList.setAdapter(mAdapter);
Log.i("StackSites", "adapter size = "+ mAdapter.getCount());
}
}
}
row_site.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp" >
<ProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/iconImg"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginRight="8dp" />
<TextView
android:id="@+id/nameTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/iconImg"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/aboutTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/iconImg"
android:textSize="12sp"
android:layout_below="@id/nameTxt"
/>
<TextView
android:id="@+id/titleTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/iconImg"
android:textSize="12sp"
android:layout_below="@id/nameTxt"
/>
</RelativeLayout>
SitesXmlPullParser.Java
package com.ryan.bobxmlpullproject;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import android.content.Context;
public class SitesXmlPullParser {
static final String KEY_SITE = "tradeSummary";
static final String KEY_NAME = "userAlias";
//static final String KEY_LINK = "link";
static final String KEY_ABOUT = "title";
static final String KEY_IMAGE_URL = "thumbnailImageURL";
public static List<StackSite> getStackSitesFromFile(Context ctx) {
// List of StackSites that we will return
List<StackSite> stackSites;
stackSites = new ArrayList<StackSite>();
// temp holder for current StackSite while parsing
StackSite curStackSite = null;
// temp holder for current text value while parsing
String curText = "";
try {
// Get our factory and PullParser
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xpp = factory.newPullParser();
// Open up InputStream and Reader of our file.
FileInputStream fis = ctx.openFileInput("StackSites.xml");
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
// point the parser to our file.
xpp.setInput(reader);
// get initial eventType
int eventType = xpp.getEventType();
// Loop through pull events until we reach END_DOCUMENT
while (eventType != XmlPullParser.END_DOCUMENT) {
// Get the current tag
String tagname = xpp.getName();
// React to different event types appropriately
switch (eventType) {
case XmlPullParser.START_TAG:
if (tagname.equalsIgnoreCase(KEY_SITE)) {
// If we are starting a new <site> block we need
//a new StackSite object to represent it
curStackSite = new StackSite();
}
break;
case XmlPullParser.TEXT:
//grab the current text so we can use it in END_TAG event
curText = xpp.getText();
break;
case XmlPullParser.END_TAG:
if (tagname.equalsIgnoreCase(KEY_SITE)) {
// if </site> then we are done with current Site
// add it to the list.
stackSites.add(curStackSite);
} else if (tagname.equalsIgnoreCase(KEY_NAME)) {
// if </name> use setName() on curSite
curStackSite.setName(curText);
} //else if (tagname.equalsIgnoreCase(KEY_LINK)) {
// if </link> use setLink() on curSite
//curStackSite.setLink(curText);
// }
else if (tagname.equalsIgnoreCase(KEY_ABOUT)) {
// if </about> use setAbout() on curSite
curStackSite.setAbout(curText);
} else if (tagname.equalsIgnoreCase(KEY_IMAGE_URL)) {
// if </image> use setImgUrl() on curSite
curStackSite.setImgUrl(curText);
}
break;
default:
break;
}
//move on to next iteration
eventType = xpp.next();
}
} catch (Exception e) {
e.printStackTrace();
}
// return the populated list.
return stackSites;
}
}
SitesAdapter.java
package com.ryan.bobxmlpullproject;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.assist.ImageLoadingListener;
/*
* Custom Adapter class that is responsible for holding the list of sites after they
* get parsed out of XML and building row views to display them on the screen.
*/
public class SitesAdapter extends ArrayAdapter<StackSite> {
ImageLoader imageLoader;
DisplayImageOptions options;
public SitesAdapter(Context ctx, int textViewResourceId, List<StackSite> sites) {
super(ctx, textViewResourceId, sites);
//Setup the ImageLoader, we'll use this to display our images
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(ctx).build();
imageLoader = ImageLoader.getInstance();
imageLoader.init(config);
//Setup options for ImageLoader so it will handle caching for us.
options = new DisplayImageOptions.Builder()
.cacheInMemory()
.cacheOnDisc()
.build();
}
/*
* (non-Javadoc)
* @see android.widget.ArrayAdapter#getView(int, android.view.View, android.view.ViewGroup)
*
* This method is responsible for creating row views out of a StackSite object that can be put
* into our ListView
*/
@Override
public View getView(int pos, View convertView, ViewGroup parent){
RelativeLayout row = (RelativeLayout)convertView;
Log.i("StackSites", "getView pos = " + pos);
if(null == row){
//No recycled View, we have to inflate one.
LayoutInflater inflater = (LayoutInflater)parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = (RelativeLayout)inflater.inflate(R.layout.row_site, null);
}
//Get our View References
final ImageView iconImg = (ImageView)row.findViewById(R.id.iconImg);
TextView nameTxt = (TextView)row.findViewById(R.id.nameTxt);
TextView titleTxt = (TextView)row.findViewById(R.id.titleTxt);
TextView aboutTxt = (TextView)row.findViewById(R.id.aboutTxt);
final ProgressBar indicator = (ProgressBar)row.findViewById(R.id.progress);
//Initially we want the progress indicator visible, and the image invisible
indicator.setVisibility(View.VISIBLE);
iconImg.setVisibility(View.INVISIBLE);
//Setup a listener we can use to swtich from the loading indicator to the Image once it's ready
ImageLoadingListener listener = new ImageLoadingListener(){
@Override
public void onLoadingStarted(String arg0, View arg1) {
// TODO Auto-generated method stub
}
@Override
public void onLoadingCancelled(String arg0, View arg1) {
// TODO Auto-generated method stub
}
@Override
public void onLoadingComplete(String arg0, View arg1, Bitmap arg2) {
indicator.setVisibility(View.INVISIBLE);
iconImg.setVisibility(View.VISIBLE);
}
@Override
public void onLoadingFailed(String arg0, View arg1, FailReason arg2) {
// TODO Auto-generated method stub
}
};
//Load the image and use our options so caching is handled.
imageLoader.displayImage(getItem(pos).getImgUrl(), iconImg,options, listener);
//Set the relavent text in our TextViews
nameTxt.setText(getItem(pos).getName());
aboutTxt.setText(getItem(pos).getAbout());
titleTxt.setText(getItem(pos).getAbout());
return row;
}
}
Downloader.java
package com.ryan.bobxmlpullproject;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import android.util.Log;
/*
* Helper class for downloading a file.
*/
public class Downloader {
//Tag for Log statements
private static String myTag = "StackSites";
//Handler msg that represents we are posting a progress update.
static final int POST_PROGRESS = 1;
/************************************************
* Download a file from the Internet and store it locally
*
* @param URL - the url of the file to download
* @param fos - a FileOutputStream to save the downloaded file to.
************************************************/
public static void DownloadFromUrl(String URL, FileOutputStream fos) { //this is the downloader method
try {
URL url = new URL(URL); //URL of the file
//keep the start time so we can display how long it took to the Log.
long startTime = System.currentTimeMillis();
Log.d(myTag, "download begining");
/* Open a connection to that URL. */
URLConnection ucon = url.openConnection();
// this will be useful so that you can show a tipical 0-100% progress bar
//int lenghtOfFile = ucon.getContentLength();
Log.i(myTag, "Opened Connection");
/************************************************
* Define InputStreams to read from the URLConnection.
************************************************/
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
Log.i(myTag, "Got InputStream and BufferedInputStream");
/************************************************
* Define OutputStreams to write to our file.
************************************************/
BufferedOutputStream bos = new BufferedOutputStream(fos);
Log.i(myTag, "Got FileOutputStream and BufferedOutputStream");
/************************************************
* Start reading the and writing our file.
************************************************/
byte data[] = new byte[1024];
//long total = 0;
int count;
//loop and read the current chunk
while ((count = bis.read(data)) != -1) {
//keep track of size for progress.
//total += count;
//write this chunk
bos.write(data, 0, count);
}
//Have to call flush or the file can get corrupted.
bos.flush();
bos.close();
Log.d(myTag, "download ready in "
+ ((System.currentTimeMillis() - startTime))
+ " milisec");
} catch (IOException e) {
Log.d(myTag, "Error: " + e);
}
}
}
StackSite.java
package com.ryan.bobxmlpullproject;
/*
* Data object that holds all of our information about a StackExchange Site.
*/
public class StackSite {
private String name;
private String link;
private String about;
private String imgUrl;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getAbout() {
return about;
}
public void setAbout(String about) {
this.about = about;
}
public String getImgUrl() {
return imgUrl;
}
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
}
@Override
public String toString() {
return "StackSite [name=" + name + ", link=" + link + ", about="
+ about + ", imgUrl=" + imgUrl + "]";
}
}
请帮忙,这是我在应用程序中遇到的最后一个问题,并希望能够让它正常工作
可以在此处找到XML文件:https://www.dropbox.com/s/w463wkx85dlbtbx/iPhoneSearch.xml
日志:
03-02 21:02:51.280 1532-1532/com.ryan.bobxmlpullproject I/StackSites﹕ OnCreate()
03-02 21:02:51.316 1532-1532/com.ryan.bobxmlpullproject I/StackSites﹕ starting download Task
03-02 21:02:51.322 1532-1551/com.ryan.bobxmlpullproject D/StackSites﹕ download begining
03-02 21:02:51.332 1532-1552/com.ryan.bobxmlpullproject D/OpenGLRenderer﹕ Render dirty regions requested: true
03-02 21:02:51.334 1532-1551/com.ryan.bobxmlpullproject I/StackSites﹕ Opened Connection
03-02 21:02:51.356 1532-1532/com.ryan.bobxmlpullproject D/﹕ HostConnection::get() New Host Connection established 0xacf3cf30, tid 1532
03-02 21:02:51.394 1532-1532/com.ryan.bobxmlpullproject D/Atlas﹕ Validating map...
03-02 21:02:51.442 1532-1552/com.ryan.bobxmlpullproject D/libEGL﹕ loaded /system/lib/egl/libEGL_emulation.so
03-02 21:02:51.443 1532-1552/com.ryan.bobxmlpullproject D/libEGL﹕ loaded /system/lib/egl/libGLESv1_CM_emulation.so
03-02 21:02:51.459 1532-1552/com.ryan.bobxmlpullproject D/libEGL﹕ loaded /system/lib/egl/libGLESv2_emulation.so
03-02 21:02:51.475 1532-1552/com.ryan.bobxmlpullproject D/﹕ HostConnection::get() New Host Connection established 0xa4816120, tid 1552
03-02 21:02:51.493 1532-1552/com.ryan.bobxmlpullproject I/OpenGLRenderer﹕ Initialized EGL, version 1.4
03-02 21:02:51.618 1532-1552/com.ryan.bobxmlpullproject D/OpenGLRenderer﹕ Enabling debug mode 0
03-02 21:02:51.651 1532-1552/com.ryan.bobxmlpullproject W/EGL_emulation﹕ eglSurfaceAttrib not implemented
03-02 21:02:51.652 1532-1552/com.ryan.bobxmlpullproject W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xa48192a0, error=EGL_SUCCESS
03-02 21:02:54.308 1532-1551/com.ryan.bobxmlpullproject I/StackSites﹕ Got InputStream and BufferedInputStream
03-02 21:02:54.308 1532-1551/com.ryan.bobxmlpullproject I/StackSites﹕ Got FileOutputStream and BufferedOutputStream
03-02 21:02:54.317 1532-1551/com.ryan.bobxmlpullproject D/StackSites﹕ download ready in 2996 milisec
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ org.xmlpull.v1.XmlPullParserException: unterminated entity ref (position:TEXT @32:51 in java.io.BufferedReader@f91f5f1)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at org.kxml2.io.KXmlParser.readEntity(KXmlParser.java:1219)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at org.kxml2.io.KXmlParser.readValue(KXmlParser.java:1401)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at org.kxml2.io.KXmlParser.next(KXmlParser.java:393)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at org.kxml2.io.KXmlParser.next(KXmlParser.java:313)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at com.ryan.bobxmlpullproject.SitesXmlPullParser.getStackSitesFromFile(SitesXmlPullParser.java:94)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at com.ryan.bobxmlpullproject.MainActivity$SitesDownloadTask.onPostExecute(MainActivity.java:97)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at com.ryan.bobxmlpullproject.MainActivity$SitesDownloadTask.onPostExecute(MainActivity.java:80)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at android.os.AsyncTask.finish(AsyncTask.java:632)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at android.os.AsyncTask.access$600(AsyncTask.java:177)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:102)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at android.os.Looper.loop(Looper.java:135)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5221)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at java.lang.reflect.Method.invoke(Native Method)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:372)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
03-02 21:02:54.318 1532-1532/com.ryan.bobxmlpullproject W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
03-02 21:02:54.325 1532-1532/com.ryan.bobxmlpullproject W/ImageLoader﹕ Unable to create external cache directory
03-02 21:02:54.332 1532-1532/com.ryan.bobxmlpullproject I/StackSites﹕ adapter size = 0
答案 0 :(得分:0)
你的xml很糟糕。结束标记是&lt; / Root&gt;
它应该是&lt; / root&gt;