• Android使用网络技术,通过网络看世界


    前言

    本文讲解Android进行网络访问及解析常用网络数据格式(XML,JSON )的方法。

    九、Android使用网络技术,通过网络看世界

    9.1 WebView控件使用介绍

    WebView控件是Android提供给开发者用于将网页内容内嵌到自己的应用程序。

    如通过WebView控件在应用程序中展示百度首页的示例代码如下:

    1. 布局代码
    
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <WebView
            android:id="@+id/web_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
    LinearLayout>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. java代码
    WebView webView=findViewById(R.id.web_view);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.setWebViewClient(new WebViewClient());//使得网页在当前Android应用程序中展示
    webView.loadUrl("http://www.baidu.com");
    
    • 1
    • 2
    • 3
    • 4
    1. 添加网络许可
    
    <uses-permission android:name="android.permission.INTERNET"/>
    
    
    • 1
    • 2
    • 3

    9.2 使用HTTP协议访问网络

    9.2.1 使用HttpURLConnection访问网络

    获取数据的使用流程:

    1. 通过URL对象的openConnection方法获取HttpURLConnection对象
    2. 为HttpURLConnection对象设置一些参数
    3. 通过HttpURLConnection对象的getInputStream方法获取网页内容的流数据
    4. 解析流数据,获取数据

    核心代码示例:

    HttpURLConnection urlConnection;
    InputStream inputStream;
    BufferedReader bufferedReader;
     //1. 获取HttpURLConnection对象
    URL url = new URL("http://www.baidu.com");
    urlConnection = (HttpURLConnection) url.openConnection();
    //2. 设置访问网络相关参数
    urlConnection.setRequestMethod("GET");
    urlConnection.setConnectTimeout(6000);
    urlConnection.setReadTimeout(6000);
    //3. 获取流数据
    inputStream = urlConnection.getInputStream();
    //4. 解析流数据
    bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
    StringBuilder response = new StringBuilder();
    String line="";
    while ((line=bufferedReader.readLine())!=null)
    {
    	response.append(line);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    向数据库提交数据(post)与向数据库获取数据(get)类似,核心改动如下:

    urlConnection.setRequestMethod("POST");
    outputStream = urlConnection.getOutputStream();
    DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
    dataOutputStream.writeBytes("usename=admin&&password=123")
    
    • 1
    • 2
    • 3
    • 4

    9.2.2 使用OkHttp访问网络

    OkHttp是一款开源的网络通信包。

    1. OkHttp使用GET请求核心代码如下:
    //1. 实例化OkHttpClient 
    OkHttpClient okHttpClient=new OkHttpClient();
    //2. 设置请求参数
    Request request = new Request.Builder()
                   		 .url("http://baidu.com")
                    	 .build();
    //3. 执行请求
    Response response = okHttpClient.newCall(request).execute();
    //4. 获取请求内容
    String responseData = response.body().string();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. OkHttp使用POST请求核心代码如下:
    //1. 实例化OkHttpClient 
    OkHttpClient okHttpClient=new OkHttpClient();
    //2. 设置向服务器提交的数据
    RequestBody requestBody = new FormBody.Builder()
                    .add("username", "mekeater")
                    .add("password", "123")
                    .build();
    //3. 设置请求参数 
    Request request = new Request.Builder()
                    .url("http://baidu.com")
                    .post(requestBody)
                    .build();
    //4. 执行请求
    Response response = okHttpClient.newCall(request).execute();
    //5. 获取请求内容
    String responseData = response.body().string();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    9.3 析网络获得的XML格式数据

    网络传输数据最常用的格式有两种分别是XML和JSON数据格式。本节先来讲讲如何解析XML格式的网络数据。

    比如我们要解析的XML文件内容如下:

    <apps>
    	<app>
    		<id>1id>
    		<name>Googlename>
    		<version>1.1version>
    	app>
    	<app>
    		<id>2id>
    		<name>Google plusname>
    		<version>2.1version>
    	app>
    	<app>
    		<id>3id>
    		<name>Google playname>
    		<version>3.0version>
    	app>
    apps>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    9.3.1 Pull解析方式

    Pull方式主要是通过识别XML文件中节点的类型,来解析数据。我认为这个没什么好解释的,大家看一下示例代码就明白如何用Pull解析XML了。

    private void parseXMLWithPull(String xmlData) {
            try {
                XmlPullParserFactory pullParserFactory = XmlPullParserFactory.newInstance();
                XmlPullParser pullParser = pullParserFactory.newPullParser();
                pullParser.setInput(new StringReader(xmlData));
                int eventType = pullParser.getEventType();
                String id="";
                String name="";
                String version="";
                while (eventType!=XmlPullParser.END_DOCUMENT)//END_DOCUMENT代表xml文档读取完成
                {
                    String nodeName=pullParser.getName();
                    switch (eventType)
                    {
                        case XmlPullParser.START_TAG://<...>这个标签开始的都是START_TAG
                            if ("id".equals(nodeName))
                                id=pullParser.nextText();
                            else if ("name".equals(nodeName))
                                name=pullParser.nextText();
                            else if ("version".equals(nodeName))
                                version=pullParser.nextText();
                            break;
                        case XmlPullParser.END_TAG://<.../>这个标签结尾的都是END_TAG
                            if ("app".equals(nodeName))
                            {
                                Log.d(TAG, "id = "+id);
                                Log.d(TAG, "name = "+name);
                                Log.d(TAG, "version = "+version);
                            }
                            break;
                        default:
                            break;
                    }
                    eventType=pullParser.next();//获取标签类型,是START_TAG还是END_TAG,或者是END_DOCUMENT
                }
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    9.3.2 SAX解析方式

    SAX解析方式是通过创建一个继承自DefaultHandler的类,然后重写startDocument,startElement,characters,endElement,endDocument,5个方法,这5个方法从名称上也很容易理解,SAX将不同的节点类型封装在不同的方法中,startDocument发生在开始解析XML文件时,startElement发生在开始解析某一个节点的时候,characters发生在获取解决节点内容的时候,endElement发生在解析一个节点完成的时候,endDocument发生在整个XML文档解析完成的时候,啰嗦这么多,其实看下示例代码就都懂了,上代码:

    import android.util.Log;
    
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
    
    public class ContentHandler extends DefaultHandler {
    
        private static final String TAG = "ContentHandler";
    
        private String nodeName;
        private StringBuilder id;
        private StringBuilder name;
        private StringBuilder version;
    
        @Override
        public void startDocument() throws SAXException {
            id=new StringBuilder();
            name=new StringBuilder();
            version=new StringBuilder();
        }
    
        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            super.startElement(uri, localName, qName, attributes);
            //记录当前开始节点的名称
            nodeName=localName;
        }
    
        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            //匹配节点名称,读取节点内容
            if (nodeName.equals("id"))
                id.append(ch,start,length);
            else if (nodeName.equals("name"))
                name.append(ch,start,length);
            else if (nodeName.equals("version"))
                version.append(ch,start,length);
        }
    
        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            //根据结束节点名称,判断是否打印内容
            if ("app".equals(localName))
            {
                Log.d(TAG, "id = "+id.toString().trim());
                Log.d(TAG, "name = "+name.toString().trim());
                Log.d(TAG, "version = "+version.toString().trim());
                id.setLength(0);
                name.setLength(0);
                version.setLength(0);
            }
        }
    
        @Override
        public void endDocument() throws SAXException {
            super.endDocument();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    具体使用示例代码如下:

       private void parseXMKWithSAX(String xmlData)
        {
            try {
                SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
                XMLReader xmlReader = saxParserFactory.newSAXParser().getXMLReader();
                ContentHandler contentHandler = new ContentHandler();
                xmlReader.setContentHandler(contentHandler);
                xmlReader.parse(new InputSource(new StringReader(xmlData)));
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    9.4 解析网络获得的JSON格式数据

    本节示例代码解析的JSON内容如下:

    [{"id":"4","version":"4.0","name":"sun1"},
    {"id":"5","version":"5.0","name":"sun2"},
    {"id":"6","version":"6.0","name":"sun3"}]
    
    • 1
    • 2
    • 3

    9.4.1 使用JSONObject解析

    JSONObject解析JSON文件非常简单,直接上示例代码:

    private void parseJSONWithJSONObject(String jsonData)
        {
            try {
                JSONArray jsonArray = new JSONArray(jsonData);
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);//每个{}中的内容
                    String id = jsonObject.getString("id");
                    String name = jsonObject.getString("name");
                    String version = jsonObject.getString("version");
                    Log.d(TAG, "id = "+id);
                    Log.d(TAG, "name = "+name);
                    Log.d(TAG, "version = "+version);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    9.4.2 使用GSON解析

    1. 定义包含每个节点所有属性
    
    public class App {
        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;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    1. 使用GSON解析JSON文件
     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(TAG, "id = "+app.getId());
                Log.d(TAG, "name = "+app.getName());
                Log.d(TAG, "version = "+app.getVersion());
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    参考书籍:第一行代码

    链接:https://pan.baidu.com/s/1aXtOQCXL6qzxEFLBlqXs1Q?pwd=n5ag
    提取码:n5ag

  • 相关阅读:
    CREATE SECURITY LABEL COMPONENT 语句2
    Flutter 精品项目大全之 蛋糕店在线商城项目支持定义tabbar(教程含源码)
    企业电子招标采购系统源码Spring Boot + Mybatis + Redis + Layui + 前后端分离 构建企业电子招采平台之立项流程图
    LeetCode--230. 二叉搜索树中第K小的元素(C++描述)
    springboot整合layui排坑
    Android的View绑定实现----编译时注解实现findViewById和setOnClickListener方式
    循环优先级仲裁~位屏蔽仲裁算法
    物流信息混合查询,多家快递同时查询省时又省力
    温湿度传感器原理介绍
    【UiPath2022+C#】UiPath 调试
  • 原文地址:https://blog.csdn.net/qq_34720818/article/details/128052513