博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【android】线程方法整理(未完)
阅读量:4144 次
发布时间:2019-05-25

本文共 4755 字,大约阅读时间需要 15 分钟。

这里是链接... 能放上去吗??

为什么要开一个新线程:

在Android4.0以后,在主线程中的HTTP请求,运行时都会报错 ANRs (“Application Not Responding”),”应用没有响应“。

所以当进行网络请求的时候 还是需要开辟一个子线程,然后等到数据返回成功后再刷新UI。

重新看json 一、传统方法:

1 请求数据五步走 cilent request response body parse

private void sendRequestWithOkHttp() {        new Thread(new Runnable() {            @Override            public void run() {                try {                    OkHttpClient client = new OkHttpClient();                    Request request = new Request.Builder()                            // 指定访问的服务器地址是电脑本机                            .url("http://10.0.2.2/get_data.json")                            .build();                    Response response = client.newCall(request).execute();                    String responseData = response.body().string();                    parseJSONWithJSONObject(responseData);                } catch (Exception e) {                    e.printStackTrace();                }            }        }).start();    }

2 对于数据进行解析

1 JSONArray对象 构造函数中放入获得的response.body 类型为string

(而这个response是client通过newCall发送request 来execute获得的 具体可以看上面
2.jsonArray为数组 定义JSONObject 其方法为jsonArray.getJSONObject(i)
3 jsonObject.getString(“id”)
循环遍历这个JSONArray ,从中取出的每一个元素都是一个JSONObject 对象,每个JSONObject 对象中又会包含id 、name 和version 这些数据。接下来只需要调用getString() 方法将这些数据取出,并打印出来即可。
下面是具体代码

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("MainActivity", "id is " + id);                Log.d("MainActivity", "name is " + name);                Log.d("MainActivity", "version is " + version);            }        } catch (Exception e) {            e.printStackTrace();        }    }

二、谷歌提供的GSON开源库

  • compile ‘com.google.code.gson:gson:2.7’
    它主要就是可以将一段JSON格式的字符串自动映射成一个对象,不需要我们再手动去编写代码进行解析了。
  • 可以定义一个Person 类,并加入name 和age 这两个字段,然后只需简单地调用如下代码就可以将JSON数据自动解析成一个Person 对象了:
    Gson gson = new Gson();
    Person person = gson.fromJson(jsonData, Person.class);
  • 如果需要解析的是一段JSON数组会稍微麻烦一点,我们需要借助TypeToken将期望解析成的数据类型传入到fromJson() 方法中,如下所示:
    List people = gson.fromJson(jsonData, new TypeToken<List>() {}.getType());
    此外,要加入id 、name 和version,新建了一个app类。**成员变量私有,重写了getter和setter方法以供外部访问。**并且此时 setName 变量名大写qwq
public String getId() { return id; } public void setId(String id) { this.id = id; }

前方代码一致和上个一致。后面就简单起来了:

private void parseJSONWithGSON(String jsonData) {        Gson gson = new Gson();        List
appList = gson.fromJson(jsonData, new TypeToken
>() {}.getType()); for (App app : appList) { Log.d("MainActivity", "id is " + app.getId());// 其他相同 } }

这样就可以 获取并且解析JSON数据并且log出解析的具体了

三、网络编程的最佳实践

通常情况下我们都应该将这些通用的网络操作提取到一个公共的类里,并提供一个静态方法

public static String sendHttpRequest(String address) {
在获取到服务器响应的数据后,我们就可以对它进行解析和处理了。但是需要注意,网络请求通常都是属于耗时操作,而sendHttpRequest() 方法的内部并没有开启线程,这样就有可能导致在调用sendHttpRequest() 方法的时候使得主线程被阻塞住。
以及,若直接在方法内开一个县城,所有的耗时逻辑都是在子线程里进行的,sendHttpRequest() 方法会在服务器还没来得及响应的时候就执行结束了,当然也就无法返回响应的数据了。 我们就需要Java的回调机制
public interface HttpCallbackListener {
void onFinish(String response);
void onError(Exception e);
}
但是 我们可以使用okhttp的 它给我们封装好了 很多东西

public static void sendOkHttpRequest(String address, **okhttp3.Callback callback**) {        OkHttpClient client = new OkHttpClient();        Request request = new Request.Builder()                .url(address)                .build();        client.newCall(request).enqueue(callback);    }

okhttp3.Callback 参数是OkHttp库中自带的一个回调接口,类似于我们刚才自己编写的HttpCallbackListener

OkHttp在enqueue() 方法的内部帮我们开好了子线程,然后会在子线程中去执行HTTP请求,并将最终的请求结果回调到okhttp3.Callback 当中。在调用sendOkHttpRequest() 方法的时候就可以这样写:

HttpUtil.sendOkHttpRequest("http://www.baidu.com", new okhttp3.Callback() {@Override    public void onResponse(Call call, Response response) throws IOException {        // 得到服务器返回的具体内容        String responseData = response.body().string();    }    @Override    public void onFailure(Call call, IOException e) {        // 在这里对异常情况进行处理    }});

注意写法 这里 是调用的时候那个括号直接括进来搞的qwq

  • [] 此处可补充有实验qwq

四、探究 服务


注意理解:

但是需要注意,网络请求通常都是属于耗时操作,而sendHttpRequest() 方法的内部并没有开启线程,这样就有可能导致在调用sendHttpRequest() 方法的时候使得主线程被阻塞住。

你可能会说,很简单嘛,在sendHttpRequest() 方法内部开启一个线程不就解决这个问题了吗?其实没有你想象中的那么容易,因为如果我们在sendHttpRequest() 方法中开启了一个线程来发起HTTP请求,那么服务器响应的数据是无法进行返回的,所有的耗时逻辑都是在子线程里进行的,sendHttpRequest() 方法会在服务器还没来得及响应的时候就执行结束了,当然也就无法返回响应的数据了。

最终的回调接口都还是在子线程中运行的,因此我们不可以在这里执行任何的UI操作,除非借助runOnUiThread() 方法来进行线程转换


或许我错了 写博客真正的意图是写和整理 就像最初开始做题的时候的感觉 而不是边写边巴拉巴拉 这样写了只是记录而已 自己回去看也看不懂 真的有意义吗

转载地址:http://dguti.baihongyu.com/

你可能感兴趣的文章
在有序的数列中查找某数,若该数在此数列中,则输出它所在的位置,否则输出no found
查看>>
万年历
查看>>
作为码农你希望面试官当场指出你错误么?有面试官这样遭到投诉!
查看>>
好多程序员都认为写ppt是很虚的技能,可事实真的是这样么?
查看>>
如果按照代码行数发薪水会怎样?码农:我能刷到公司破产!
查看>>
程序员失误造成服务停用3小时,只得到半月辞退补偿,发帖喊冤
查看>>
码农:很多人称我“技术”,感觉这是不尊重!纠正无果后果断辞职
查看>>
php程序员看过来,这老外是在吐糟你吗?看看你中了几点!
查看>>
为什么说程序员是“培训班出来的”就是鄙视呢?
查看>>
码农吐糟同事:写代码低调点不行么?空格回车键与你有仇吗?
查看>>
阿里p8程序员四年提交6000次代码的确有功,但一次错误让人唏嘘!
查看>>
一道技术问题引起的遐想,最后得出结论技术的本质是多么的朴实!
查看>>
985硕士:非科班自学编程感觉还不如培训班出来的,硕士白读了?
查看>>
你准备写代码到多少岁?程序员们是这么回答的!
查看>>
码农:和产品对一天需求,产品经理的需求是对完了,可我代码呢?
查看>>
程序员过年回家该怎么给亲戚朋友解释自己的职业?
查看>>
技术架构师的日常工作是什么?网友:搭框架,写公共方法?
查看>>
第四章 微信飞机大战
查看>>
九度:题目1008:最短路径问题
查看>>
九度Online Judge
查看>>