Android中的网路与数据(二)

Android中的网路与数据(二)

前情提要:在上一篇文章中,我们已经从0开始进行了几个尝试。并且成功的从网络中获取到了数据。

但是这个数据是以二进制的形式展现出来的。那么这篇博客就将数据进行处理并且封装成方法。

对网络流中数据进行处理

首先对数据处理之前,我们先看看数据是什么:

emmm,这种东西肯定不是我们想获取的数据吧。我们想要的数据至少也是给人看的。不管是什么东西,至少你得变成英文吧。

设置“阅读器”

而现在是用数组的方式展示的。那人自然是看不懂的。所以我们该怎么办呢?

很简单!设置编码格式就好了!

private void getData() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                URL url = null;
                try {
                    url = new URL("https://www.baidu.com");
                    HttpURLConnection conn = ((HttpURLConnection) url.openConnection());
                    conn.setRequestMethod("POST");
                    // 获取连接的输入流
                    InputStream inputStream = conn.getInputStream();
                    // 新建“阅读器”。可以为流设置编码格式
                    BufferedReader br = new BufferedReader(
                            new InputStreamReader(inputStream, "utf-8")
                    );
​
                    StringBuilder data = new StringBuilder();
                    // 一次读一行,读到空就跳出
                    while (br.readLine() != null) {
                        data.append(br.readLine());
                    }
​
                    // 在主线程中设置内容
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            setData(data.toString());
                        }
                    });
​
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
    }

如果你有不太明白的地方,请综合上一篇博客内容,或者给我留言

相比之前,我们只是为流添加了一个BufferReader。这个BufferReader就像一个阅读器。可以从流中读取二进制编码,然后将这个集按照设置的格式进行解码。

发生了什么?

就像是WPS一样。他能读取一个*.doc的文件,并且按照规则,设置字体的大小、粗细、颜色等等。

这个BufferReader就像一个WPS。而流就是一个Word文件。按照UTF-8的格式进行翻译。就这样我们得到了:

这下看懂了。哪怕我看不懂其他的,最中间的百度一下也是映入眼帘。这下至少是人能看懂的了。

一些思考

但是我们知道,直接访问www.baidu.com的话。看到的内容并不是这种吧。

当我们用浏览器访问时,浏览器会自动对HTML进行解析并进行更深的操作。而我们只是去读取到了一个HTML,如果没有解析看到的就是这样的效果。如果了解过web就会感到好理解的多。

总结与问题

至此,我们在MainActivity中进行了网络请求,并且获取数据,最后展示出来。我们经历了

  • 设置网络权限(只用设置一次)

  • 新建线程

  • 在线程中进行网络请求

  • 为数据创建“阅读器”,并进行翻译

  • 在主线程中设置内容

这个过程不算困难,但可以说非常复杂了。如果我们在很多的活动中都需要网络请求,并在请求的基础上做了更深的操作,就要写很多相似甚至重复的代码。至少我是非常不爽的。因此我想要进行一下自己的尝试。

将网络请求进行封装

Java是一个面向对象的语言

如果我将网络请求封装成一个类。需要进行请求时,只需要调用,这样我就不用再走一遍那一套了。但是,我们该怎么做?

分析

既然我们要封装了,那就必须为这个方法设置一些形参与返回值,来适应各种各样的场合。

需要的数据

在各种请求中,不是所有请求都访问一个地址。操作也是各种各样。

比如,这里需要图片,那里需要文本,请求的地址肯定是不一样的。另外,获取到了数据,进行的处理也是各种各样。因此,一个简单的方法就出现了,我们需要的是一个地址(String)和操作(Runnable)

返回的数据

有需要就有返回。不同的类在不同的请求里,对不同的结果做不同的处理。

举个栗子:在登录界面,如果登录成功,我需要进行跳转;失败了,需要进行提示。而加载数据界面,成功了需要展示数据;失败,返回上一个界面。如此,我们就简单返回是否成功(boolean)

而且,大多时候,还需要从网络流中获取的数据。姑且认为数据是字符串类型。因此,传递一个参数data(StringBuilder)用来接受数据

封装

新建一个Java,就叫HttpUtil了。简单编写代码

public class HttpUtil {
​
    /**
     * 进行网络请求,封装数据
     *
     * @param url 访问的地址
     * @param toData 封装的参数 用数组封装下,以便在线程中访问数据并返回
     * @param runnable 回调的行为
     * @return 是否成功
     */
    public static boolean post(String url,StringBuilder[] toData, Runnable runnable)  {
        try {
            // 新建一个线程
            new Thread(new Runnable() {
​
                @Override
                public void run() {
                    try {
                        // 创建连接
                        URL httpUrl = new URL(url);
                        HttpURLConnection connection = (HttpURLConnection) httpUrl.openConnection();
                        connection.setRequestMethod("POST");
​
                        // 获取连接的输入流
                        InputStream inputStream = connection.getInputStream();
                        // 创建“阅读器”
                        BufferedReader br = new BufferedReader(
                                new InputStreamReader(inputStream, "utf-8")
                        );
​
                        // 处理数据
                        StringBuilder data = new StringBuilder("这是被封装处理的数据");
​
                        while (br.readLine() != null) {
                            data.append(br.readLine());
                        }
​
                        toData[0] = data;
​
                        // 回调
                        runnable.run();
​
                    } catch (Exception e) {
                        e.printStackTrace();
                        throw new RuntimeException();
                    }
                }
            }).start();
            return true;
        } catch (Exception e) {
            return false;
        }
​
    }
​
}
​

此时我们的Main成了这样:

public class MainActivity extends AppCompatActivity {
​
    private TextView tv;
​
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
​
        tv = findViewById(R.id.textView);
​
        getData();
    }
​
    private void getData() {
        // 封装数组
        StringBuilder[] data = {new StringBuilder()};
        // 直接调用(匿名内部类Runnable)
        boolean result = HttpUtil.post("https://www.baidu.com/", data, new Runnable() {
            @Override
            public void run() {
                // 别忘了在主线程中进行设置数据操作
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        setData(data[0].toString());
                    }
                });
            }
        });
​
    }
​
    private void setData(String data) {
        tv.setText(data);
    }
}

看效果:

这样,就做到了封装进行的操作啦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飛_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值