Android网络编程

sekobe 8年前
   <h2>1.XML和JSON格式数据</h2>    <p>通常情况下,每一个需要访问网络的应用程序都会有一个自己的服务器,应用可以向服务器提交数据,也可以从服务器上获取数据。应用(客户端)和服务器之间 的数据传输常见格式有XML和JSON格式。</p>    <p>i.下面是XML格式的一个例子</p>    <pre>  <code class="language-java"><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></code></pre>    <p>语法如下:</p>    <pre>  <code class="language-java">a)、任何的起始标签都必须有一个结束标签。  b)、可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在大于符号之前紧跟一个斜线(/),例如<百度百科词条/>。XML解析器会将其翻译成<百度百科词条></百度百科词条>。  c)、标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签,例如这是一串百度百科中的样例字符串。这好比是将起始和结束标签看作是数学中的左右括号:在没有关闭所有的内部括号之前,是不能关闭外面的括号的。  d)、所有的特性都必须有值。  e)、所有的特性都必须在值的周围加上双引号。</code></pre>    <p>ii.JSON例子</p>    <pre>  <code class="language-java">[{"id":"1","version":"1.2","name":"Tom"},  {"id":"2","version":"2.2","name":"Jack"},  {"id":"3","version":"1.6","name":"Tomson"}]</code></pre>    <p>语法如下:</p>    <pre>  <code class="language-java">JSON 语法是 JavaScript 对象表示语法的子集。  -数据在键值对中  -数据由逗号分隔  -花括号保存对象  -方括号保存数组</code></pre>    <h2>3.前期准备</h2>    <p>i.OKhttp</p>    <p>这里使用Square公司的OKHTTP框架,添加依赖:</p>    <pre>  <code class="language-java">compile 'com.squareup.okhttp3:okhttp:3.6.0'</code></pre>    <p>ii.需要联网权限:</p>    <pre>  <code class="language-java"><uses-permission android:name="android.permission.INTERNET" /></code></pre>    <p>iii.Apache http 服务器准备</p>    <p>下载: 链接:http://pan.baidu.com/s/1qXZGqmg 密码:rj7x</p>    <p>下载得到msi文件,点击安装,安装教程很多,我不赘述了。</p>    <p style="text-align: center;">然后再浏览器输入: 127.0.0.1<br> <img src="https://simg.open-open.com/show/76673a259badcca6da07b0a4cbd06af4.png"></p>    <p>出现 IT WORKS! 说明服务器安装成功</p>    <p>最后是准备数据源:</p>    <p>新建data.xml包含数据:</p>    <pre>  <code class="language-java"><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></code></pre>    <p>在浏览器输入 http://127.0.0.1/data.xml ,出现如下如下界面,说明数据准备成功:</p>    <p><img src="https://simg.open-open.com/show/114ff4dd1e8695744424b7530f37e4f7.png"></p>    <p>新建 data.json:</p>    <pre>  <code class="language-java">[{"id":"1","version":"1.2","name":"Tom"},  {"id":"2","version":"2.2","name":"Jack"},  {"id":"3","version":"1.6","name":"Tomson"}]</code></pre>    <p>在浏览器输入 http://127.0.0.1/data.json ,出现如下如下界面,说明数据准备成功:</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/653c5a647a3d23ed719642857cb7143e.png"></p>    <h2>4.解析XML</h2>    <p>解析XML主要有:PULL解析方法和SAX解析方法。</p>    <p>做好前期准备,新建一个项目。</p>    <p>i.PULL解析方式:</p>    <p>PullMainActivity .java</p>    <pre>  <code class="language-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("http://10.0.2.2/data.xml").build();                  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>    <p>xml:</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"      xmlns:tools="http://schemas.android.com/tools"      android:id="@+id/activity_main"      android:layout_width="match_parent"      android:layout_height="match_parent"      android:paddingBottom="@dimen/activity_vertical_margin"      android:paddingLeft="@dimen/activity_horizontal_margin"      android:paddingRight="@dimen/activity_horizontal_margin"      android:paddingTop="@dimen/activity_vertical_margin"      tools:context="com.example.geekp.internet.xml.PullMainActivity">        <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>    <p>运行结果:</p>    <p><img src="https://simg.open-open.com/show/f9cf8d8dbc0fe45dd2b346330819cd03.gif"></p>    <p>从上面的代码中,我们可以看到PULL关键的代码是:</p>    <pre>  <code class="language-java">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();                      }</code></pre>    <p>首先要获取一个XmlPullParserFactory的实例,并借助这个实例得到XMLPullparser对象,然后调用setInput的方法将服务器返回的数据设置进去就可以开始解析了。</p>    <p>ii.SAX解析方式</p>    <p>通常需要写一个DefaultHandler的子类并实现下面的五个方法:</p>    <pre>  <code class="language-java">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>    <p>下面来看个例子:</p>    <p>ContentHandler .java</p>    <pre>  <code class="language-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>    <p>SAXainActivity .java</p>    <pre>  <code class="language-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("http://10.0.2.2/data.xml").build();                  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>    <p>xml:</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"      xmlns:tools="http://schemas.android.com/tools"      android:id="@+id/activity_main2"      android:layout_width="match_parent"      android:layout_height="match_parent"      android:paddingBottom="@dimen/activity_vertical_margin"      android:paddingLeft="@dimen/activity_horizontal_margin"      android:paddingRight="@dimen/activity_horizontal_margin"      android:paddingTop="@dimen/activity_vertical_margin"      tools:context="com.example.geekp.internet.xml.SAXainActivity">        <Button          android:id="@+id/btnrequest"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:text="请求" />  </RelativeLayout></code></pre>    <p>效果图:</p>    <p><img src="https://simg.open-open.com/show/f9cf8d8dbc0fe45dd2b346330819cd03.gif"></p>    <p>得到服务器的数据之后,首先创建了一个 SAXParserFactory 的实例然后再获取 XMLReader 对象,接着将我们编好的DefaultHandler子类设置到 XMLReader 中,最后调用parse().</p>    <p>整个工程的源码, <a href="/misc/goto?guid=4959748366962184560" rel="nofollow,noindex">请点击这里下载</a></p>    <h2>5.解析JSon格式的数据</h2>    <p>解析JSon格式的数据通常有JSONObject和GSON两种方式:</p>    <h2>i.JSONObject</h2>    <pre>  <code class="language-java">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("http://10.0.2.2/data.json")                          .build();                  try {                      Response response = httpclient.newCall(request).execute();                      String data = response.body().string();                        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>    <p>xml:</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"      xmlns:tools="http://schemas.android.com/tools"      android:id="@+id/activity_main"      android:layout_width="match_parent"      android:layout_height="match_parent"      android:paddingBottom="@dimen/activity_vertical_margin"      android:paddingLeft="@dimen/activity_horizontal_margin"      android:paddingRight="@dimen/activity_horizontal_margin"      android:paddingTop="@dimen/activity_vertical_margin"      tools:context="com.example.geekp.json.JSONObjectMainActivity">        <Button          android:id="@+id/btnsend"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:text="请求" />  </RelativeLayout></code></pre>    <p>效果:</p>    <p><img src="https://simg.open-open.com/show/7a57c2c60abac59b83abf5f32f129fcd.gif"></p>    <p>由于我们在服务器中定义的是一个JSon数组,因此我们需要先将返回的数组传到一个JSONArray对象中,然后再遍历这个数组。</p>    <p>ii.GSON方式</p>    <p>GSON是一个开源库,使用它首先得添加依赖:</p>    <pre>  <code class="language-java">compile 'com.google.code.gson:gson:2.8.0'</code></pre>    <p>Bean.java</p>    <pre>  <code class="language-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>    <p>GsonMainActivity .java</p>    <pre>  <code class="language-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("http://10.0.2.2/data.json")                          .build();                  try {                      Response response = httpclient.newCall(request).execute();                      String data = response.body().string();                      parseJSonWithGSON(data);                  } catch (IOException e) {                      e.printStackTrace();                  }              }          }).start();      }        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>    <p>xml:</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"      xmlns:tools="http://schemas.android.com/tools"      android:id="@+id/activity_gson_main"      android:layout_width="match_parent"      android:layout_height="match_parent"      android:paddingBottom="@dimen/activity_vertical_margin"      android:paddingLeft="@dimen/activity_horizontal_margin"      android:paddingRight="@dimen/activity_horizontal_margin"      android:paddingTop="@dimen/activity_vertical_margin"      tools:context="com.example.geekp.json.gson.GsonMainActivity">        <Button          android:id="@+id/btnsendre"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:text="请求" />  </RelativeLayout></code></pre>    <p>这样也可以成功地解析JSON数据了;</p>    <p><img src="https://simg.open-open.com/show/7a57c2c60abac59b83abf5f32f129fcd.gif"></p>    <p> </p>    <p> </p>    <p>来自:http://www.androidchina.net/6554.html</p>    <p> </p>