08. Android基础——解析数据

WebView

  1. 可以在应用程序中嵌入一个浏览器

  2. 例子

    1. 定义一个控件

      <WebView
              android:id="@+id/web_view"
              android:layout_width="match_parent"
              android:layout_height="match_parent" />
      
    2. 编写MainActivity中的逻辑

      public class MainActivity extends AppCompatActivity {
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
      
              WebView webView = (WebView) findViewById(R.id.web_view);
              // 使用getSettings()方法去设置一些浏览器的属性
              webView.getSettings().setJavaScriptEnabled(true);
      
              // 调用setWebViewClient()方法,传入了一个WebViewClient实例,
              // 这样当需要从一个网页跳转到另一个网页的时候,目标网页仍然在WebView中显示,不用打开系统浏览器
              webView.setWebViewClient(new WebViewClient());
              webView.loadUrl("http://www.baidu.com");
          }
      }
      
    3. 在AndroidManifest.xml中声明权限

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

HTTP相关

HttpURLConnection

  1. Android上本来有两种发送HTTP请求的方式,在Android6.0中,HttpClient被移除了,就剩下HttpURLConnection

  2. 例子

    URL url = new URL("https://www.baidu.com");
    
    // 获取HttpURLConnection的实例
    HttpURLConnection connection = (HttpURLConnection)url.openConnection();
    
    // 设置HTTP请求使用的方法(GET和SET)
    connection.seetRequestMethod("GET");
    
    // 设置连接超时
    connection.setTimeout(6000);
    
    // 设置读取超时
    connection.setReadIimeout(4000);
    
    // 获取服务器返回的输入流
    InputStream is = connection.getInputStream();
    
    // 操作完之后关闭连接
    connection.disconnect();
    

OkHttp

  1. Square公司开发的第三方网络通信库

  2. 添加依赖(app/build.gradle)

    implementation 'com.google.android.exoplayer:extension-okhttp:2.17.1'
    
  3. 例子

    1. 发起GET请求

      // 创建一个实例
      OkHttpClient client = new OkHttpClient();
      
      // 创建一个Request对象
      Request request = new Request.Builder()
          .url("https://www.baidu.com")
          .build();
      
      // 调用newCall()方法创建一个Call对象,然后调用其中的execute()方法发送请求并获取返回数据
      Response response = client.newCall(request).execute();
      
      // 获取返回的数据
      String responseData = response.body().string();
      
    2. 发起POST请求

      // 创建一个实例
      OkHttpClient client = new OkHttpClient();
      
      // 构造一个RequestBody对象来存放要提交的参数
      RequestBody requestBody = new FormBody.Builder()
          .add("username","admin")
          .add("password","123456")
          .build();
      
      // 调用post()方法,
      Request request = new Request.Builder()
          .url("https://www.baidu.com")
          .post(requestBody)
          .build();
      
      // 调用newCall()方法创建一个Call对象,然后调用其中的execute()方法发送请求并获取返回数据
      Response response = client.newCall(request).execute();
      
      // 获取返回的数据
      String responseData = response.body().string();
      

解析XML格式数据

  1. 假设有如下待解析的xml数据

    <apps>
        <app>
            <id>1</id>
            <name>Tom</name>
            <age>17</age>
        </app>
        <app>
            <id>2</id>
            <name>Jack</name>
            <age>18</age>
        </app>
        <app>
            <id>3</id>
            <name>Helen</name>
            <age>19</age>
        </app>
    
    </apps>
    

Pull解析XML格式

  1. 例子

          private void sendRequestWithOkHttp() {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        OkHttpClient client = new OkHttpClient();
                        Request request = new Request.Builder()
                                .url("http://127.0.0.1/data.xml")
                                .build();
                        Response response = client.newCall(request).execute();
                        String responseData = response.body().string();
                        parseXMLWithPull(responseData);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    private void parseXMLWithPull(String xmlData) {
            try {
                XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
                XmlPullParser xmlPullParser = factory.newPullParser();
                xmlPullParser.setInput(new StringReader(xmlData));
                int eventType = xmlPullParser.getEventType();
    
                String id = "";
                String name = "";
                String age = "";
                while (eventType != XmlPullParser.END_DOCUMENT) {
                    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 ("age".equals(nodeName)) {
                                age = xmlPullParser.nextText();
                            }
                            break;
                        }
                        // 解析完成
                        case XmlPullParser.END_TAG: {
                            if ("app".equals(nodeName)) {
                                Log.d("MainActivity", "id is " + id);
                                Log.d("MainActivity", "name is " + name);
                                Log.d("MainActivity", "age is " + age);
                            }
                            break;
                        }
                        default:
                            break;
                    }
                    eventType = xmlPullParser.next();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    • 在parseXMLWithPull()方法中
    • 首先获取一个XmlPullParserFactory的实例,然后拿到XmlPullParser对象
    • 调用setInput()方法将服务器返回的XML数据设置进去
    • 通过getEventType()方法拿到当前要解析的内容,然后通过while循环进行解析
    • while循环中的判断条件是只要待解析的内容不是XmlPullParse.END_DOCUMENT,就继续调用next()方法解析

SAX解析XML格式

  1. 自定义一个类继承DefalutHandler,然后重写父类中的方法

    public class MyHandler extends DefaultHandler {
        private String nodeName;
        private StringBuilder id;
        private StringBuilder name;
        private StringBuilder age;
    
        @Override
        public void startDocument() throws SAXException {
             // 初始化StringBuilder对象
            id = new StringBuilder();
            name = new StringBuilder();
            age = 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 ("age".equals(nodeName)) {
                age.append(ch, start, length);
            }
        }
    
        @Override
        public void endElement(String uir, String localName, String qName) throws SAXException {
            if ("app".equals(localName)) {
                
                // trim()方法用来删除字符串头尾的空白符(包括空格,制表符,换行符)
                Log.d("MyHandler", "id is" + id.toString().trim());
    
                // 最后清空StringBuilder
                id.setLength(0);
                name.setLength(0);
                age.setLength(0);
            }
    
        }
    
        @Override
        public void endDocument() throws SAXException {
            super.endDocument();
        }
    }
    
    
    • startDocument():在开始解析XML的时候调用
    • startElement():在开始解析某个节点的时候调用
    • characters():在获取节点中内容的时候调用
    • endElement():在完成解析某个节点的时候调用
    • endDocument():在完成整个XML解析的时候调用
  2. 然后定义方法

        private void parseXMLWithSAX(String xmlData){
            try {
                // 创建一个SAXParserFactory对象
                SAXParserFactory factory = SAXParserFactory.newInstance();
                
                // 获取XMLReader对象
                XMLReader xmlReader = factory.newSAXParser().getXMLReader();
                MyHandler handler = new MyHandler();
                
                // 将上面编写的MyHandler的实例设置到XMLReader中
                xmlReader.setContentHandler(handler);
                
                // 调用xmlReader中的parse()方法开始解析
                xmlReader.parse(new InputSource(new StringReader(xmlData)));
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    

解析JSON格式数据

  1. 假设有如下待解析的JSON格式数据

    [{"id":5,"gender":"male","name":"Owen"},
     {"id":6,"gender":"female","name":"Mia"},
     {"id":7,"gender":"male","name":"Marcus"}]
    

JSONObject解析JSON数据

  1. JSONObject是官方提供的

  2. 例子

    private void parseJSONWithJSONObject(String jsonData){
            try {
                // 创建一个JSONArray对象,将数据传进去
                JSONArray jsonArray = new JSONArray(jsonData);
                
                // 循环变量jsonArray,里面的每一个元素都是一个JSONObject对象
                // 调用getString()方法将其中的数据取出并打印出来
                for (int i=0;i<jsonArray.length();i++){
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    String id = jsonObject.getString("id");
                    String name = jsonObject.getString("name");
                    String gender = jsonObject.getString("gender");
                    Log.d("MainActivity","name is "+name);
                }
            } catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    

使用GSON解析JSON数据

  1. 谷歌提供的GSON开源库

  2. 添加依赖(app/build.grade)

    implementation 'com.google.code.gson:gson:2.8.6'
    
  3. GSON可以将一段JSON格式的字符串自动映射成一个对象

    1. 假设有一段JSON数据如下

      {"name":"Tom","age":15}
      
    2. 调用GSON解析这段数据

      Gson gson = new Gson();
      Person person = gson.fromJson(jsonData,Person.class);
      
    3. 解析一段JSON数组

      List<Person> people = gson.fromJson(jsonData,new TypeToken<list<Person>>(){}.getType())
      
  4. 例子

    1. 首先新建一个类

      import com.google.gson.Gson;
      import com.google.gson.reflect.TypeToken;
      import java.util.List;
      
      
      package com.example.networktest;
      
      public class App {
          private String id;
          private String name;
          private String gender;
      
          public String getId() {
              return id;
          }
      
          public String getName() {
              return name;
          }
      
          public String getGender() {
              return gender;
          }
      
          public void setId(String id) {
              this.id = id;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public void setGender(String gender) {
              this.gender = gender;
          }
      }
      
      
    2. 定义解析方法

      private void parseJSONWithGSON(String jsonData){
              Gson gson = new Gson();
              List<App> appList = gson.fromJson(jsonData,new TypeToken<List<App>>(){}.getType());
              for (App app:appList){
                  Log.d("MainActivity","id is "+app.getId());
              }
          }
      
      • 这里需要借助TypeToken<T>将需要解析成的数据类型传入到fromJson()方法中
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容