目录

HttpURLConnection执行网络请求+json数据解析并输出到RecyclerView

利用 HttpURLConnection 从后端拽取数据展示在app上

1.获取数据

代码如下:

 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
    //开启线程来发起网络请求获取数据
    private void sendRequestWithHttpURLConnection(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connection = null;
                BufferedReader reader = null;
                try {
                    URL url = new URL("www.baidu.com");
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    InputStream in = connection.getInputStream();
                    //对获取到的输入流进行读取
                    reader = new BufferedReader(new InputStreamReader(in));
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null){
                        response.append(line);
                    }
                    Log.e("测试","获取到的数据:"+response);
                } catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    if (reader != null) try {
                        reader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    if (connection != null){
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }

分析:由于执行网络请求属于耗时操作,需要开启子线程执行,有关多线程常用方法点击链接跳转;url 为 后端地址,这里输入的是百度首页地址;设置最大请求时长为8秒:Timeout(8000);将获取的数据读取到 response,并使用 Log.e 调试输出。运行程序后即可看到百度首页的数据构成

2.json数据解析

我们从后端获取的数据是以字符串的形式传输的,但实际上它具有一定的数据结构,常用的形式有 xml 和 json;这里探究 json 数据的解析

首先将 response 转成字符串并传输到函数 showResponse中:在Log.e调试修改为

1
2
Log.e("测试","获取到的数据:"+response);
showResponse(response.toString());

2.1便于理解但很麻烦的方法:JSONObject

大致写一下思路:将字符串转成json数据类型,遍历所有数据获取信息并封装为 list。但是操作过于繁琐。

 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
private void showResponse (final String response) {
        if(response!=null) {
            Map<String, Object> map;
            List<Map<String, Object>> list = new ArrayList<>();
            try {
                JSONArray jsonArray = new JSONArray(response);
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    map = new HashMap<>();
                    if (jsonObject != null) {
                        int id = jsonObject.optInt("id");
                        String name = jsonObject.optString("name");
                        String content = jsonObject.optString("content");
                        boolean favor = jsonObject.optBoolean("favor");
                        JSONArray son = jsonObject.getJSONArray("son");
                        map.put("id", id);
                        map.put("name", name);
                        map.put("content", content);
                        map.put("favor", favor);
                    }
                    list.add(map);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

2.2使用 Gson 解析工具

引入工具包

implementation 'com.google.code.gson:gson:2.8.5'

使用AS插件 GsonFormat

新建 JavaBean 类,我这里命名为 chapter,将json数据复制到 GsonFormat ,点击OK,自动根据 json 结构生成 JavaBean 类。

声明全局变量

public ArrayList<chapter> list = new ArrayList<>();

解析过程

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
	//解析json传入list
    private void showResponse (final String response) {
        Gson gson = new Gson();
        Type listType = new TypeToken<List<chapter>>() {
        }.getType();
        list = gson.fromJson(response, listType);
        Message msg = new Message();
        msg.what = 1;
        handler.sendMessage(msg);
    }

注:不同结构的 json 数据写法也不太相同,点击链接查看官方文档

2.3阿里的fastjson解析工具(没用过)

3.在RecyclerView中展示数据

我们已经获得一个封装好的 list,使用 handler 方法更新 ui

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
	//在RecycleView中展示数据,点击item页面跳转
    @SuppressLint("HandlerLeak")
    public Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case 1:
                    RecyclerView recyclerview = findViewById(R.id.recy);
                    if (recyclerview.getItemDecorationCount() == 0 ) {
                        recyclerview.addItemDecoration(new DividerItemDecoration(ChapterActivity.this, DividerItemDecoration.VERTICAL));
                    }
                    chapter_itemAdapter adapter = new chapter_itemAdapter(list,ChapterActivity.this,Word);
                    //设置布局格式
                    recyclerview.setLayoutManager(new LinearLayoutManager(ChapterActivity.this));
                    recyclerview.setAdapter(adapter);
                    break;
            }
        }
    };

创建适配器 chapter_itemAdapter

 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
public class chapter_itemAdapter extends RecyclerView.Adapter<chapter_itemAdapter.ViewHolder> {
    private ArrayList<chapter> list;
    public Context context;
    private LayoutInflater inflater;
    chapter_itemAdapter(ArrayList<chapter> list, Context context){
        this.context = context;
        this.list = list;
        inflater = LayoutInflater.from(context);
    }
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = inflater.inflate( R.layout.recyclerview_item , parent, false);
        return new ViewHolder(view);
    }
    @Override
    public int getItemCount() {
        return list.size();
    }
    @Override
    public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
holder.recy_name.setText(Html.fromHtml(Objects.requireNonNull(list.get(position).getName())).toString());
    }
    class ViewHolder extends RecyclerView.ViewHolder{
        TextView recy_name;
        ViewHolder(View itemView) {
            super(itemView);
            recy_name = itemView.findViewById(R.id.recy_name);
        }
    }
}

对应布局 recyclerview_item

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <LinearLayout
        android:id="@+id/LinearLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/touch_bg"
        android:orientation="vertical"
        tools:ignore="UselessParent">
        <TextView
            android:id="@+id/recy_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingTop="20dp"
            android:paddingBottom="5dp"
            android:paddingStart="15dp"
            android:paddingEnd="15dp"
            android:textColor="#00BBD3"
            android:textSize="17sp"/>
    </LinearLayout>
</RelativeLayout>

有关RecyclerView更多用法点击链接跳转