1.Android网络请求与数据解析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qingjianduoyun/article/details/80614786

一、原生数据解析

1.要完成的效果

如下图所示,点击按钮跳转到另一个Activity,从服务器请求数据并在页面中在预定位置显示出来。
这里写图片描述

2.网络数据接口和数据结构及内容

url地址:http://www.imooc.com/api/teacher?type=3&cid=1
数据如下:

{
    "status": 1,
    "data": {
        "title": "Tony老师聊shell——环境变量配置文件作者",
        "author": "Tony",
        "content": "本课程是《Tony老师聊shell》系列课程的第三篇,为你带来常用的环境变量配置文件的使用。"
    },
    "msg": "成功"
}

3.新建项目

1.新建一个名为HttpDemo的项目,activity_main.xml代码如下:

<?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:gravity="center"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:paddingRight="15dp"
        android:text="网络操作与数据解析" />
</LinearLayout>

对应的MainActivity.java的代码为:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.btn_net).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //点击按钮后页面跳转
                startActivity(new Intent(MainActivity.this, DetailActivity.class));
            }
        });
    }
}

2.在Android Studio中单击菜单栏File-->New-->Activity-->EmptyActivity,Activity名为DetailActivity,Layout名为activity_detailactivity_detail.xml代码如下所示:

<?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/content_detail"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".DetailActivity"
    tools:showIn="@layout/activity_detail">

    <TextView
        android:id="@+id/titlename"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:gravity="center"
        android:textSize="24sp" />

    <TextView
        android:id="@+id/author"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:gravity="right"
        android:paddingRight="10dp"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="8dp"
        android:layout_marginTop="15dp"
        android:layout_weight="1"
        android:lineSpacingMultiplier="1.5"
        android:textSize="20sp" />
</LinearLayout>

4.网络请求及数据解析

首先来分析一下步骤,使用HttpUrlConnection去做网络请求及数据解析主要分为以下4个步骤:
1. 实例化一个url对象【参数:你要访问的接口地址】
2. 获取HttpUrlConnection对象
3. 设置请求连接属性
4. 获取响应吗,判断是否连接成功,若连接成功,则读取输入流并解析
要注意的有:访问网络的操作不能在UI线程中进行,需开辟新线程来操作,并且要借助Handler来完成线程间的通信(UI线程与开辟的用于网络请求及数据解析的线程),并且还要新建一个Essay类进行线程间信息的传输。

Essay.java代码如下(对应了详情页DetailActivity页面的三项内容):

public class Essay {
    private String title;
    private String author;
    private String content;

    public Essay(String title, String author, String content) {
        this.title = title;
        this.author = author;
        this.content = content;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

网络请求及数据解析主要在详情页进行,详情页面DetailActivity.java代码如下:

public class DetailActivity extends AppCompatActivity {
    private TextView titleTextView, authorTextView, contentTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);
        initView();
        initData();
    }

    private void initView() {
        titleTextView = findViewById(R.id.titlename);
        authorTextView = findViewById(R.id.author);
        contentTextView = findViewById(R.id.content);
    }

    private void initData() {
        /*开辟一个新线程*/
        new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    //1、实例化一个url对象【参数:你要访问的接口地址】
                    URL url = new URL("http://www.imooc.com/api/teacher?type=3&cid=1");
                    //2、获取HttpUrlConnection对象
                    HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                    //3、设置请求连接属性
                    httpURLConnection.setRequestMethod("GET");
                    httpURLConnection.setReadTimeout(6000);
                    //4、获取响应吗,判断是否连接成功,若连接成功,则读取输入流并解析
                    if (httpURLConnection.getResponseCode() == 200) {
                        //4-1、获取输入流
                        InputStream is = httpURLConnection.getInputStream();
                        byte[] b = new byte[1024 * 512];
                        int length = 0;
                        //4-2、建立缓存流,保存所读取的字节数组
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        while ((length = is.read(b)) > -1) {
                            //4-3、将读取的字节数组写入到缓存流中
                            baos.write(b, 0, length);
                        }
                        Log.e("TAG", baos.toString());
                        //4-4、JSON数据解析
                        JSONObject object = new JSONObject(baos.toString());
                        int status = object.getInt("status");
                        String msg = object.getString("msg");
                        Log.e("TAG", status + "  " + msg);
                        //若是对象就用JSONObject进行解析,若是数组则用JSONArray进行解析
                        JSONObject data = object.getJSONObject("data");
                        String title = data.getString("title");
                        String author = data.getString("author");
                        String content = data.getString("content");
                        Log.e("TAG", "  标题:" + title + "  作者:" + author + "  内容:" + content);
                        //将操作权交还主线程
                        Message message = handler.obtainMessage();
                        Essay essay = new Essay(title, author, content);
                        message.obj = essay;
                        //调用此方法则会触发主线程中handler对象中的重写的handleMessage方法
                        handler.sendMessage(message);
                    }

                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }.start();

    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Essay essay = (Essay) msg.obj;
            titleTextView.setText(essay.getTitle());
            authorTextView.setText(essay.getAuthor());
            contentTextView.setText(essay.getContent());
        }
    };
}

二、Gson数据解析

使用Gson来解析数据就方便多了,修改上面DetailActivity.java中的代码,主要修改json数据解析的代码,下面将整个initData()方法中的代码贴出来:

private void initData() {
        new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    //1、实例化一个url对象【参数:你要访问的接口地址】
                    URL url = new URL("http://www.imooc.com/api/teacher?type=3&cid=1");
                    //2、获取HttpUrlConnection对象
                    HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                    //3、设置请求连接属性
                    httpURLConnection.setRequestMethod("GET");
                    httpURLConnection.setReadTimeout(6000);
                    //4、获取响应吗,判断是否连接成功,若连接成功,则读取输入流并解析
                    if (httpURLConnection.getResponseCode() == 200) {
                        //4-1、获取输入流
                        InputStream is = httpURLConnection.getInputStream();
                        byte[] b = new byte[1024 * 512];
                        int length = 0;
                        //4-2、建立缓存流,保存所读取的字节数组
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        while ((length = is.read(b)) > -1) {
                            //4-3、将读取的字节数组写入到缓存流中
                            baos.write(b, 0, length);
                        }
                        Log.e("TAG", baos.toString());
                        //4-4、JSON数据解析
                        JSONObject object = new JSONObject(baos.toString());
                        int status = object.getInt("status");
                        String msg = object.getString("msg");
                        Log.e("TAG", status + "  " + msg);
                        //创建Gson对象
                        Gson gson = new Gson();
                        String data = object.getString("data");
                        Essay e = gson.fromJson(data, Essay.class);
                        //将操作权交还主线程
                        Message message = handler.obtainMessage();
                        //Essay essay = new Essay(title, author, content);
                        message.obj = e;
                        //调用此方法则会触发主线程中handler对象中的重写的handleMessage方法
                        handler.sendMessage(message);
                    }

                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

三、复杂数据的解析

数据接口如下:

{
    "status": 1,
    "data": [
        {
            "id": 1,
            "name": "Tony老师聊shell——环境变量配置文件",
            "picSmall": "http://img.mukewang.com/55237dcc0001128c06000338-300-170.jpg",
            "picBig": "http://img.mukewang.com/55237dcc0001128c06000338.jpg",
            "description": "为你带来shell中的环境变量配置文件",
            "learner": 12312
        }, {
            "id": 2,
            "name": "数学知识在CSS动画中的应用 ",
            "picSmall": "http://img.mukewang.com/55249cf30001ae8a06000338-300-170.jpg",
            "picBig": "http://img.mukewang.com/55249cf30001ae8a06000338.jpg",
            "description": "数学知识与CSS结合实现酷炫效果",
            "learner": 45625
        }, {
            "id": 3,
            "name": "Oracle数据库开发必备利器之PL/SQL基础",
            "picSmall": "http://img.mukewang.com/5523711700016d1606000338-300-170.jpg",
            "picBig": "http://img.mukewang.com/5523711700016d1606000338.jpg",
            "description": "Oracle数据库高级开发必备的基础。",
            "learner": 41236
        }, {
            "id": 4,
            "name": "Android见证消息推送时刻进阶篇",
            "picSmall": "http://img.mukewang.com/551e470500018dd806000338-300-170.jpg",
            "picBig": "http://img.mukewang.com/551e470500018dd806000338.jpg",
            "description": "Android消息推送就在眼前,Come on",
            "learner": 45456
        }, {
            "id": 5,
            "name": "Avalon探索之旅基础教程——复杂绑定",
            "picSmall": "http://img.mukewang.com/551de0570001134f06000338-300-170.jpg",
            "picBig": "http://img.mukewang.com/551de0570001134f06000338.jpg",
            "description": "前端迷您MVVM框架,Avalon复杂绑定属性篇。",
            "learner": 56556
        }, {
            "id": 6,
            "name": "Android-Service系列之断点续传下载",
            "picSmall": "http://img.mukewang.com/552640c300018a9606000338-300-170.jpg",
            "picBig": "http://img.mukewang.com/552640c300018a9606000338.jpg",
            "description": "想升职加薪么?本章课程你值得拥有",
            "learner": 48996
        }, {
            "id": 7,
            "name": "JUnit—Java单元测试必备工具",
            "picSmall": "http://img.mukewang.com/551b92340001c9f206000338-300-170.jpg",
            "picBig": "http://img.mukewang.com/551b92340001c9f206000338.jpg",
            "description": "Java单元测试利器!",
            "learner": 13210
        }, {
            "id": 8,
            "name": "细说Java多线程之内存可见性",
            "picSmall": "http://img.mukewang.com/5518c3d7000175af06000338-300-170.jpg",
            "picBig": "http://img.mukewang.com/5518c3d7000175af06000338.jpg",
            "description": "用两种方式实现内存可见性",
            "learner": 15051
        }, {
            "id": 9,
            "name": "CSS动画实用技巧",
            "picSmall": "http://img.mukewang.com/551b98ae0001e57906000338-300-170.jpg",
            "picBig": "http://img.mukewang.com/551b98ae0001e57906000338.jpg",
            "description": "教你使用CSS实现惊艳的动画效果!",
            "learner": 15210
        }, {
            "id": 10,
            "name": "C++远征之起航篇",
            "picSmall": "http://img.mukewang.com/550b86560001009406000338-300-170.jpg",
            "picBig": "http://img.mukewang.com/550b86560001009406000338.jpg",
            "description": "C++亮点尽在其中",
            "learner": 84545
        }
    ],
    "msg": "成功"
}

这时我们使用Android原生数据解析就比较麻烦了,而是用Gson进行数据解析就会简单许多。根据上面的接口,新建一个类Outline.java,代码如下:

package com.demo.httpdemo;

public class Outline {
    private int id;
    private String name;
    private String picSmall;
    private String picBig;
    private String description;
    private String learner;

    public Outline(int id, String name, String picSmall, String picBig, String description, String learner) {
        this.id = id;
        this.name = name;
        this.picSmall = picSmall;
        this.picBig = picBig;
        this.description = description;
        this.learner = learner;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getPicSmall() {
        return picSmall;
    }

    public void setPicSmall(String picSmall) {
        this.picSmall = picSmall;
    }

    public String getPicBig() {
        return picBig;
    }

    public void setPicBig(String picBig) {
        this.picBig = picBig;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getLearner() {
        return learner;
    }

    public void setLearner(String learner) {
        this.learner = learner;
    }
}

以下实现的效果仅仅是将数据解析并打印出来(Logcat窗口),并不会在Activity中显示出来。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initData();
    }

    private void initData() {
        new Thread() {
            @Override
            public void run() {
                try {
                    URL url = new URL("http://www.imooc.com/api/teacher?type=2");
                    HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                    httpURLConnection.setRequestMethod("GET");
                    httpURLConnection.setReadTimeout(6000);
                    if (httpURLConnection.getResponseCode() == 200) {
                        InputStream is = httpURLConnection.getInputStream();
                        byte[] b = new byte[1024 * 512];
                        int length = 0;
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        while ((length = is.read(b)) > -1) {
                            baos.write(b, 0, length);
                        }
                        Log.e("TAG", baos.toString());
                        JSONObject object = new JSONObject(baos.toString());
                        /**
                         * Gson
                         * 1、解析普通的json对象
                         * 2、解析json数组
                         */
                        Gson gson = new Gson();
                        String data = object.getString("data");
                        ArrayList<Outline> outlines = gson.fromJson(data, new TypeToken<ArrayList<Outline>>() {
                        }.getType());
                        for (int i = 0; i < outlines.size(); i++) {
                            Outline o = outlines.get(i);
                            Log.e("TAG", "id:" + o.getId() + "  name:" + o.getName() + "  picSmall:" + o.getPicSmall() +
                                    "  picBig:" + o.getPicBig() + "  description:" + o.getDescription() + "  learner" + o.getLearner());
                        }

                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    private void initView() {
        findViewById(R.id.btn_net).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this, DetailActivity.class));
            }
        });
    }
}

运行应用即可在Logcat窗口查看打印结果:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qingjianduoyun/article/details/80614786