Android網絡編程

1.XML和JSON格式數據

通常情況下,每一個需要訪問網絡的應用程序都會有一個自己的服務器,應用可以向服務器提交數據,也可以從服務器上獲取數據。應用(客戶端)和服務器之間 的數據傳輸常見格式有XML和JSON格式。

i.下面是XML格式的一個例子

<apps>
<app>
    <id>1</id>
    <name>Google Maps</name>
    <version>1.0</version>
</app>
<app>
    <id>2</id>
    <name>Chrome</name>
    <version>1.0</version>
</app>
<app>
    <id>3</id>
    <name>Google Play</name>
    <version>1.0</version>
</app>
</apps>

語法如下:

a)、任何的起始標簽都必須有一個結束標簽。
b)、可以采用另一種簡化語法,可以在一個標簽中同時表示起始和結束標簽。這種語法是在大于符號之前緊跟一個斜線(/),例如<百度百科詞條/>。XML解析器會將其翻譯成<百度百科詞條></百度百科詞條>。
c)、標簽必須按合適的順序進行嵌套,所以結束標簽必須按鏡像順序匹配起始標簽,例如這是一串百度百科中的樣例字符串。這好比是將起始和結束標簽看作是數學中的左右括號:在沒有關閉所有的內部括號之前,是不能關閉外面的括號的。
d)、所有的特性都必須有值。
e)、所有的特性都必須在值的周圍加上雙引號。

ii.JSON例子

[{"id":"1","version":"1.2","name":"Tom"},
{"id":"2","version":"2.2","name":"Jack"},
{"id":"3","version":"1.6","name":"Tomson"}]

語法如下:

JSON 語法是 JavaScript 對象表示語法的子集。
-數據在鍵值對中
-數據由逗號分隔
-花括號保存對象
-方括號保存數組

3.前期準備

i.OKhttp

這里使用Square公司的OKHTTP框架,添加依賴:

compile 'com.squareup.okhttp3:okhttp:3.6.0'

ii.需要聯網權限:

<uses-permission android:name="android.permission.INTERNET" />

iii.Apache http 服務器準備

下載: 鏈接:http://pan.baidu.com/s/1qXZGqmg 密碼:rj7x

下載得到msi文件,點擊安裝,安裝教程很多,我不贅述了。

然后再瀏覽器輸入: 127.0.0.1

出現 IT WORKS! 說明服務器安裝成功

最后是準備數據源:

新建data.xml包含數據:

<apps>
<app>
    <id>1</id>
    <name>Google Maps</name>
    <version>1.0</version>
</app>
<app>
    <id>2</id>
    <name>Chrome</name>
    <version>1.0</version>
</app>
<app>
    <id>3</id>
    <name>Google Play</name>
    <version>1.0</version>
</app>
</apps>

在瀏覽器輸入 http://127.0.0.1/data.xml ,出現如下如下界面,說明數據準備成功:

新建 data.json:

[{"id":"1","version":"1.2","name":"Tom"},
{"id":"2","version":"2.2","name":"Jack"},
{"id":"3","version":"1.6","name":"Tomson"}]

在瀏覽器輸入 http://127.0.0.1/data.json ,出現如下如下界面,說明數據準備成功:

4.解析XML

解析XML主要有:PULL解析方法和SAX解析方法。

做好前期準備,新建一個項目。

i.PULL解析方式:

PullMainActivity .java

package com.example.geekp.internet.xml;

import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.TextView; import android.widget.Toast;

import com.example.geekp.internet.R;

import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory;

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL;

import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response;

public class PullMainActivity extends AppCompatActivity { private TextView text;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    text = (TextView) findViewById(R.id.response_text);
    findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            sendRequest();
        }
    });
}

private void sendRequest() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            OkHttpClient httpclient = new OkHttpClient();

// 10.0.2.2對于模擬器來講就是PC的IP地址 Request request = new Request.Builder().url("); try { Response response = httpclient.newCall(request).execute(); String bulider = response.body().string(); parseXMLWithPull(bulider); } catch (IOException e) { e.printStackTrace(); } } }).start(); }

private void parseXMLWithPull(final String builder) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            try {
                XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
                XmlPullParser xmlPullParser = factory.newPullParser();
                xmlPullParser.setInput(new StringReader(builder));
                int eventType = xmlPullParser.getEventType();
                String id = "";
                String name = "";
                String version = "";
                while (XmlPullParser.END_DOCUMENT != eventType) {
                    String nodeName = xmlPullParser.getName();
                    switch (eventType) {
                        case XmlPullParser.START_TAG:
                            if ("id".equals(nodeName)) {
                                id = xmlPullParser.nextText();
                            } else if ("name".equals(nodeName)) {
                                name = xmlPullParser.nextText();
                            } else if ("version".equals(nodeName)) {
                                version = xmlPullParser.nextText();
                            }
                            break;
                        //完成解析某個結點
                        case XmlPullParser.END_TAG:
                            if ("app".equals(nodeName)) {
                                System.out.println(id);
                                System.out.println(name);
                                System.out.println(version);
                                Toast.makeText(getApplicationContext(),"id is:"+id+"  name is:"+name+" version is:"+version,Toast.LENGTH_SHORT).show();
                            }
                            break;
                        default:
                            break;
                    }
                    eventType = xmlPullParser.next();
                }
            } catch (XmlPullParserException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });

}

}</code></pre>

xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="

<Button
    android:id="@+id/btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Send request" />

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/response_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</ScrollView>

</LinearLayout></code></pre>

運行結果:

從上面的代碼中,我們可以看到PULL關鍵的代碼是:

XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
                    XmlPullParser xmlPullParser = factory.newPullParser();
                    xmlPullParser.setInput(new StringReader(builder));
                    int eventType = xmlPullParser.getEventType();
                    String id = "";
                    String name = "";
                    String version = "";
                    while (XmlPullParser.END_DOCUMENT != eventType) {
                        String nodeName = xmlPullParser.getName();
                        switch (eventType) {
                            case XmlPullParser.START_TAG:
                                if ("id".equals(nodeName)) {
                                    id = xmlPullParser.nextText();
                                } else if ("name".equals(nodeName)) {
                                    name = xmlPullParser.nextText();
                                } else if ("version".equals(nodeName)) {
                                    version = xmlPullParser.nextText();
                                }
                                break;
                            //完成解析某個結點
                            case XmlPullParser.END_TAG:
                                if ("app".equals(nodeName)) {
                                    System.out.println(id);
                                    System.out.println(name);
                                    System.out.println(version);
                                    Toast.makeText(getApplicationContext(),"id is:"+id+"  name is:"+name+" version is:"+version,Toast.LENGTH_SHORT).show();
                                }
                                break;
                            default:
                                break;
                        }
                        eventType = xmlPullParser.next();
                    }

首先要獲取一個XmlPullParserFactory的實例,并借助這個實例得到XMLPullparser對象,然后調用setInput的方法將服務器返回的數據設置進去就可以開始解析了。

ii.SAX解析方式

通常需要寫一個DefaultHandler的子類并實現下面的五個方法:

class MH extends DefaultHandler {
    //開始解析XML時調用
    @Override
    public void startDocument() throws SAXException {
    }

//開始解析某個結點的時候調用
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

}

//獲取結點中的內容調用
@Override
public void characters(char[] ch, int start, int length) throws SAXException {

}

//完成解析某個結點的時候調用
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {

}

//完成整個xml的時候調用
@Override
public void endDocument() throws SAXException {

}

}</code></pre>

下面來看個例子:

ContentHandler .java

package com.example.geekp.internet.xml;

//import jdk.internal.org.xml.sax.helpers.DefaultHandler;

import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler;

/**

  • Created by geekp on 2017/2/24.
  • Email:810275469@qq.com */

public class ContentHandler extends DefaultHandler { private StringBuffer id; private StringBuilder name; private StringBuilder version; private String nodeName;

@Override
public void startDocument() throws SAXException {
    id=new StringBuffer();
    name=new StringBuilder();
    version=new StringBuilder();
}

@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    //記錄當前節點的名字
    nodeName=localName;
}

@Override
public void characters(char[] ch, int start, int length) throws SAXException {
    if("id".equals(nodeName))
    {
        id.append(ch,start,length);
    }else if("name".equals(nodeName))
    {
        name.append(ch,start,length);
    }else if("version".equals(nodeName))
    {
        version.append(ch,start,length);
    }
}

@Override
public void endElement(String uri, String localName, String qName) throws SAXException {

    if("app".equals(localName))
    {
        System.out.println("id is: "+id.toString().trim());
        System.out.println("name is :" +name.toString().trim());
        System.out.println("version is :"+version.toString().trim());
        //最后要stringbuilder清空
        id.setLength(0);
        name.setLength(0);
        version.setLength(0);
    }
}

@Override
public void endDocument() throws SAXException {
    super.endDocument();
}

}</code></pre>

SAXainActivity .java

package com.example.geekp.internet.xml;

import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast;

import com.example.geekp.internet.R;

import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory;

import java.io.IOException; import java.io.StringReader;

import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory;

import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response;

public class SAXainActivity extends AppCompatActivity { private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); button=(Button)findViewById(R.id.btnrequest); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { sendRequestwithOkhttp(); } }); } private void sendRequestwithOkhttp() { new Thread(new Runnable() { @Override public void run() { OkHttpClient httpclient = new OkHttpClient(); // 10.0.2.2對于模擬器來講就是PC的IP地址 Request request = new Request.Builder().url("); try { Response response = httpclient.newCall(request).execute(); String data = response.body().string(); parseXMLWithSAX(data); } catch (IOException e) { e.printStackTrace(); } } }).start(); }

private void parseXMLWithSAX(final String data) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            SAXParserFactory factory=SAXParserFactory.newInstance();
            try {
                XMLReader reader=factory.newSAXParser().getXMLReader();
                ContentHandler contentHandler=new ContentHandler();
                //將contentHandler的實例設置到XMLreader中
                reader.setContentHandler(contentHandler);
                reader.parse(new InputSource(new StringReader(data)));
            } catch (SAXException e) {
                e.printStackTrace();
            } catch (ParserConfigurationException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });

}

}</code></pre>

xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="

<Button
    android:id="@+id/btnrequest"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="請求" />

</RelativeLayout></code></pre>

效果圖:

得到服務器的數據之后,首先創建了一個 SAXParserFactory 的實例然后再獲取 XMLReader 對象,接著將我們編好的DefaultHandler子類設置到 XMLReader 中,最后調用parse().

整個工程的源碼, 請點擊這里下載

5.解析JSon格式的數據

解析JSon格式的數據通常有JSONObject和GSON兩種方式:

i.JSONObject

package com.example.geekp.json;

import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button;

import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject;

import java.io.IOException; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response;

public class JSONObjectMainActivity extends AppCompatActivity {

private Button button;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    button = (Button) findViewById(R.id.btnsend);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            sendRequestwithOkhttp();
        }
    });
}

private void sendRequestwithOkhttp() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            OkHttpClient httpclient = new OkHttpClient();

// 10.0.2.2對于模擬器來講就是PC的IP地址 Request request = new Request.Builder() .url("

                parseJSonWithJsonObject(data);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();
}

private void parseJSonWithJsonObject(final String data) {
    try {
        JSONArray jsonArray = new JSONArray(data);
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject object = jsonArray.getJSONObject(i);
            System.out.println("id is:" + object.getString("id"));
            System.out.println("name is :" + object.getString("name"));
            System.out.println("version is:" + object.getString("version"));
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }

}

}</code></pre>

xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="

<Button
    android:id="@+id/btnsend"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="請求" />

</RelativeLayout></code></pre>

效果:

由于我們在服務器中定義的是一個JSon數組,因此我們需要先將返回的數組傳到一個JSONArray對象中,然后再遍歷這個數組。

ii.GSON方式

GSON是一個開源庫,使用它首先得添加依賴:

compile 'com.google.code.gson:gson:2.8.0'

Bean.java

package com.example.geekp.json.gson;

/**

  • Created by geekp on 2017/2/24.
  • Email:810275469@qq.com */

public class Bean { private String id; private String name; private String version;

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getVersion() {
    return version;
}

public void setVersion(String version) {
    this.version = version;
}

}</code></pre>

GsonMainActivity .java

package com.example.geekp.json.gson;

import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button;

import com.example.geekp.json.R; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken;

import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject;

import java.io.IOException; import java.util.List;

import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response;

public class GsonMainActivity extends AppCompatActivity {

private Button button;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_gson_main);
    button = (Button) findViewById(R.id.btnsendre);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            sendRequestwithOkhttp();
        }
    });
}

private void sendRequestwithOkhttp() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            OkHttpClient httpclient = new OkHttpClient();

// 10.0.2.2對于模擬器來講就是PC的IP地址 Request request = new Request.Builder() .url("

private void parseJSonWithGSON(final String data) {
    Gson gson = new Gson();
    List<Bean> beanlist = gson.fromJson(data, new TypeToken<List<Bean>>() {
    }.getType());
    for(Bean bean:beanlist)
    {
        System.out.println("id is :"+bean.getId());
        System.out.println("name is:"+bean.getName());
        System.out.println("vesrsion is :"+bean.getVersion());
    }
}

}</code></pre>

xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="

<Button
    android:id="@+id/btnsendre"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="請求" />

</RelativeLayout></code></pre>

這樣也可以成功地解析JSON數據了;

 

 

來自:http://www.androidchina.net/6554.html

 

 本文由用戶 sekobe 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!