简体   繁体   English

从Web服务器Android下载XML文件

[英]Downloading an XML file from a web server Android

I am developing an application for college that connects to a web server and reads data from an XML on the server. 我正在为大学开发一个应用程序,该应用程序连接到Web服务器并从服务器上的XML读取数据。 The appilcation is working but I am currently trying to really break down the code and understand exactly what is happening. 该应用程序正在运行,但是我目前正在尝试真正分解代码并确切了解正在发生的事情。

My question is that I have an inner class that extends the AsyncTask class. 我的问题是我有一个扩展AsyncTask类的内部类。 Within this inner class I create a new URL object and get an InputStream . 在这个内部类中,我创建一个新的URL对象并获取一个InputStream I understand that because I am doing this I can then successfully connect to the web server from the background thread and make whatever requests I like. 我知道,因为我正在这样做,所以我可以从后台线程成功连接到Web服务器,并发出我喜欢的任何请求。

In the past I always used the DefaultHttpClient to execute HTTP requests. 过去,我总是使用DefaultHttpClient执行HTTP请求。 However in this code I do not create an instance of this class anywhere. 但是,在此代码中,我不会在任何地方创建此类的实例。 Instead I just get an input stream to read in the sequence of bytes. 相反,我只是得到一个输入流以按字节顺序读取。

Could someone explain in the code below what is meant by parsing spec and also if somewhere behind the scenes a HTTP request is actually being made? 有人可以在下面的代码中解释解析规范的含义,以及是否在幕后某个地方实际发出了HTTP请求吗?

URL url = new URL("http://feeds.pcworld.com/pcworld/latestnews");

Documentation on Android Dev says: Android Dev上的文档说:

Creates a new URL instance by parsing spec. 通过解析规范创建一个新的URL实例。

This is my entire MainActivity 这是我的整个MainActivity

public class MainActivity extends ListActivity {

List<Item>items;//Holds item objects containing info relating to element pulled from XML file.
Item item; //Instance of Item - contains all data relating to a specific Item.
ArticleListAdapter adapter;//Generates the Views and links the data source (ArrayList) to the ListView.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //Set the layout
    setContentView(R.layout.activity_main);

    //initialize variables
    items = new ArrayList<Item>();

    //Perform a http request for the file on the background thread. 
    new PostTask().execute();

    //Create instance of the adapter and pass the list of items to it.
    adapter = new ArticleListAdapter(this, items);

    //Attach adapter to the ListView.
    setListAdapter(adapter);        

}


private InputStream getInputStream(URL url) {
    try{
        return url.openConnection().getInputStream();
    }catch(IOException e){
        return null;
    }
}

/**
 * Executed when an Item in the List is clicked. Will display the article being clicked in a browser.
 */
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    //Get the link from the item object stored in the array list
    Uri uri = items.get(position).getLink();
    //Create new intent to open browser
    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    startActivity(intent);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

//ASYNC CLASS
private class PostTask extends AsyncTask<String, Integer, String>{

    @Override
    protected String doInBackground(String... arg0) {
        try{
            //link to data source
            URL url = new URL("http://feeds.pcworld.com/pcworld/latestnews");

            //Set up parser
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            factory.setNamespaceAware(false);
            XmlPullParser xpp = factory.newPullParser();

            //get XML from input stream
            InputStream in = getInputStream(url);
            if (in == null) {
                throw new Exception("Empty inputstream");
            }
            xpp.setInput(in, "UTF_8");

            //Keep track of which tag inside of XML
            boolean insideItem = false;

            //Loop through the XML file and extract data required
            int eventType = xpp.getEventType();

            while (eventType != XmlPullParser.END_DOCUMENT) {

                if (eventType == XmlPullParser.START_TAG) {
                    Log.v("ENTER", String.valueOf(xpp.getEventType()));

                    if (xpp.getName().equalsIgnoreCase("item")) {
                        insideItem = true;

                        //Create new item object
                        item = new Item();

                    } else if (xpp.getName().equalsIgnoreCase("title")) {
                        if (insideItem){
                            item.setTitle(xpp.nextText());
                            Log.i("title", item.getTitle());
                        }

                    } 

                    else if (xpp.getName().equalsIgnoreCase("description")) {
                        if (insideItem){
                            item.setDescription(xpp.nextText());
                        }
                    }

                    else if (xpp.getName().equalsIgnoreCase("link")) {
                        if (insideItem){
                            item.setLink(Uri.parse(xpp.nextText()));                            
                        }
                    }
                }else if(eventType==XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item")){

                    //If no longer inside item tag then we know we are finished parsing data relating to one specific item.
                    insideItem=false;
                    //add item to list
                    items.add(item);

                }


                eventType = xpp.next(); //move to next element
                publishProgress(); //update progress on UI thread.
            }


                } catch (MalformedURLException e) {

                    e.printStackTrace();

                } catch (XmlPullParserException e) {

                    e.printStackTrace();

                } catch (IOException e) {

                    e.printStackTrace();

                }
                catch (Exception e) {

                    e.printStackTrace();

                }


        return "COMPLETED";
    }

    /*
     * Update the List as each item is parsed from the XML file.
     * @see android.os.AsyncTask#onProgressUpdate(Progress[])
     */
    @Override
    protected void onProgressUpdate(Integer... values) {
        adapter.notifyDataSetChanged();

    }

    /*
     * Runs on UI thread after doInBackground is finished executing.
     * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
     */
    public void onPostExecute(String s) {
        //Toast message to inform user of how many articles have been downloaded.
        Toast.makeText(getApplicationContext(), s + " Items: " + items.size(), Toast.LENGTH_SHORT).show();
        adapter.notifyDataSetChanged();
    }

}

} }

I am sorry if this question is very basic, but like I said I am trying to learn and that is what this site is all about right? 很抱歉,如果这个问题是非常基本的,但是就像我说的那样,我正在尝试学习,这就是该网站的全部内容吗?

I'd appreciate any feedback or help people have in relation to this topic. 感谢您对本主题的任何反馈或帮助。 Many thanks! 非常感谢!

parsing spec - means it will parse the string you pass to the constructor. parsing spec -表示它将解析您传递给构造函数的字符串。 The URL API creators just named this string (url/uri) in a more generic way - the spec. URL API创建者只是以一种更通用的方式(即规范)来命名此字符串(url / uri)。 Probably because it specifies the resource to which you will connect. 可能是因为它指定了您要连接的资源。 If string does not represent a valid URL, then it throws MalformedURLException . 如果字符串不代表有效的URL,则抛出MalformedURLException After parsing it knows what host, port, path, etc. to use for making the HTTP request. 解析后,它知道用于发出HTTP请求的主机,端口,路径等。

The fact of creating a URL instance does not mean any networking happens. 创建URL实例的事实并不意味着发生任何联网。 It is similar to File API - where creating a File instance does not open/read/write anything. 它类似于File API-在其中创建File实例不会打开/读取/写入任何内容。

url.openConnection().getInputStream() - here is where networking happens (an HTTP request is fired). url.openConnection().getInputStream() -这是进行网络连接的地方(触发了HTTP请求)。

Here is the source code of ULR: http://www.docjar.com/html/api/java/net/URL.java.html So you can look how it works. 这是ULR的源代码: http : //www.docjar.com/html/api/java/net/URL.java.html这样您就可以了解它的工作原理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM