• Android应用:实现网络加载商品数据【OKHttp、Glide、Gson】


    实现网络加载商品数据的功能:

    1、在AndroidManifest.xml中声明网络权限;

    2、在app/build.gradle中添加okhttp, glide, gson等必需的第3方库;

    3、在MainActivity中通过OkHttpClient连接给定的Web服务,获取商品数据;对应的json数据为本地的json文件,名字为goods_list_data.json;数据内容为:[
    {“id”:1,“count”:“5.4万”,“goodsName”:“富士拍立得相机”,“goodsPic”:“/img/polaroid.png”},
    {“id”:2,“count”:“5.3万”,“goodsName”:“格兰仕微波炉”,“goodsPic”:“/img/microwave_oven.png”},
    {“id”:3,“count”:“1.4万”,“goodsName”:“新国标电动车”,“goodsPic”:“/img/electric_vehicle.png”},
    {“id”:4,“count”:“1.6万”,“goodsName”:“官方订制投影仪”,“goodsPic”:“/img/projector.png”},
    {“id”:5,“count”:“0.4万”,“goodsName”:“美的35L烤箱”,“goodsPic”:“/img/oven.png”},
    {“id”:6,“count”:“3.3万”,“goodsName”:“儿童学习桌”,“goodsPic”:“/img/learning_table.png”}
    ]
    对应的图片也存储在本地的img文件中

    4、使用gson库解析JSON格式的商品数据,转成java bean商品数据对象(Goods类)的列表;

    5、创建MsgHandler类,用于异步更新商品列表;

    6、在GoodsAdapter中通过glide控件加载并显示网络图片。


    1.部署网络图片资源

    首先,我们需要将对应的文件部署在一个简易的服务器(Tomcat)中,服务器中存放数据的目录结构如下图所示

    E:.
    ├─goods
    │  └─img
    │  └─goods_list_data.json
    └─WEB-INF
    
    • 1
    • 2
    • 3
    • 4
    • 5

    其中,ROOT目录在"apache-tomcat-9.0.65-windows-x64\webapps\ROOT"下,表示Tomcat服务器的根目录。

    • goods文件夹存放的是商品列表所用到的数据
    • 其中goods\img文件夹存放的是商品的图片资源
    • goods_list_data.json文件存放的是商品列表的数据,具体如下所示
    [
      {"id":1,"count":"5.4万","goodsName":"富士拍立得相机","goodsPic":"/img/polaroid.png"},
      {"id":2,"count":"5.3万","goodsName":"格兰仕微波炉","goodsPic":"/img/microwave_oven.png"},
      {"id":3,"count":"1.4万","goodsName":"新国标电动车","goodsPic":"/img/electric_vehicle.png"},
      {"id":4,"count":"1.6万","goodsName":"官方订制投影仪","goodsPic":"/img/projector.png"},
      {"id":5,"count":"0.4万","goodsName":"美的35L烤箱","goodsPic":"/img/oven.png"},
      {"id":6,"count":"3.3万","goodsName":"儿童学习桌","goodsPic":"/img/learning_table.png"}
    ]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    启动tomcat后,可访问http://localhost:8080/goods/goods_list_data.json展示信息
    在这里插入图片描述

    2.创建项目

    1. 打开Android Studio,并创建一个新的Android项目。
    2. 命名项目并选择适当的目标API级别和设备类型。
    3. 创建一个新的空白活动(Empty Activity)。

    3.在AndroidManifest.xml中声明网络权限

    在 AndroidManifest.xml 文件中添加以下权限声明,以便应用可以访问网络:

    <uses-permission android:name="android.permission.INTERNET" />
    
    • 1

    在这里插入图片描述由于网络安全策略导致的问题,即不允许在明文(非加密)的情况下与 localhost 进行通信。这通常涉及到网络安全配置,特别是在 Android 9.0(API级别28)及更高版本中引入了更严格的网络安全策略;因此我们还需要进行配置网络安全配置文件

    解决此问题的方法之一是使用 HTTPS 协议而不是 HTTP,因为 HTTPS 是加密的。

    如果在本地测试应用,可以使用 Android 的网络安全配置文件来允许明文通信。

    1. res/xml 文件夹中创建一个名为 network_security_config.xml 的网络安全配置文件。如果该文件夹不存在,请手动创建。
    
    <network-security-config>
        <base-config cleartextTrafficPermitted="true">
            <trust-anchors>
                <certificates src="system" />
                <certificates src="user" />
            trust-anchors>
        base-config>
    network-security-config>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    1. AndroidManifest.xml 文件中,将这个网络安全配置文件应用于你的应用。在 元素内添加 android:networkSecurityConfig 属性,如下所示:
    <application
        android:networkSecurityConfig="@xml/network_security_config"
        
    application>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    这将允许你的应用在本地开发和测试过程中与 localhost 进行明文通信。但请注意,在生产环境中,强烈建议使用 HTTPS 以确保数据的安全传输。

    如果你使用的是模拟器或真机设备,请确保重新构建和部署应用,以使配置生效。此外,如果你的服务器正在本地运行,请确保服务器端口和地址正确。

    4.添加依赖库

    app/build.gradle文件中添加OkHttp、Glide、Gson依赖库。

        implementation("com.squareup.okhttp3:okhttp:4.9.1")
        implementation("com.squareup.okhttp3:logging-interceptor:4.9.1")
        implementation("com.google.code.gson:gson:2.8.8")
        implementation("com.github.bumptech.glide:glide:4.12.0")
        annotationProcessor("com.github.bumptech.glide:compiler:4.12.0")
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    进行同步
    在这里插入图片描述
    等待安装依赖……

    5.创建一个XML布局文件

    res/layout文件夹中创建一个布局文件,例如activity_main.xml,用于显示商品数据。

    
    <androidx.recyclerview.widget.RecyclerView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述
    创建一个XML布局文件用于显示商品项
    res/layout文件夹中创建一个布局文件,例如item_goods.xml,用于显示每个商品项。

    
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp">
    
        <ImageView
            android:id="@+id/goodsImageView"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:scaleType="centerCrop" />
    
        <TextView
            android:id="@+id/goodsNameTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp" />
    LinearLayout>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述

    6.创建一个Java Bean类

    创建一个Goods类,用于表示商品数据。

    public class Goods {
        private int id;
        private String count;
        private String goodsName;
        private String goodsPic;
    
        // Getters and setters
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    7.创建一个适配器类

    创建一个自定义适配器类GoodsAdapter,用于将商品数据绑定到RecyclerView中。

    public class GoodsAdapter extends RecyclerView.Adapter<GoodsAdapter.ViewHolder> {
        private List<Goods> goodsList;
        private Context context;
    
        public GoodsAdapter(Context context, List<Goods> goodsList) {
            this.context = context;
            this.goodsList = goodsList;
        }
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_goods, parent, false);
            return new ViewHolder(view);
        }
    
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            Goods goods = goodsList.get(position);
            holder.goodsNameTextView.setText(goods.getGoodsName());
    
            // Load and display image using Glide
            Glide.with(context)
                .load(goods.getGoodsPic())
                .into(holder.goodsImageView);
        }
        @Override
        public int getItemCount() {
            if (goodsList != null) {
                return goodsList.size();
            } else {
                return 0; // 返回0表示没有数据
            }
        }
    
        static class ViewHolder extends RecyclerView.ViewHolder {
            TextView goodsNameTextView;
            ImageView goodsImageView;
    
            ViewHolder(View itemView) {
                super(itemView);
                goodsNameTextView = itemView.findViewById(R.id.goodsNameTextView);
                goodsImageView = itemView.findViewById(R.id.goodsImageView);
            }
        }
    }
    
    • 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

    8.实现网络加载数据

    MainActivity.java中实现网络加载商品数据的功能。请确保你的goods_list_data.json文件位于app/src/main/assets文件夹下。

    package com.leo.network;
    
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.util.Log;
    import android.view.View;
    
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import androidx.recyclerview.widget.RecyclerView;
    
    import com.google.gson.Gson;
    
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.List;
    
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    import okhttp3.Response;
    
    public class MainActivity extends AppCompatActivity {
    
        private RecyclerView recyclerView;
        private GoodsAdapter adapter;
        private List<Goods> goodsList;
    
        private static final int MSG_UPDATE_DATA = 1;
        private Handler msgHandler = new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                if (msg.what == MSG_UPDATE_DATA) {
                    adapter.notifyDataSetChanged();
                }
                return true;
            }
        });
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            recyclerView = findViewById(R.id.recyclerView);
            recyclerView.setLayoutManager(new LinearLayoutManager(this));
            adapter = new GoodsAdapter(this, goodsList);
            recyclerView.setAdapter(adapter);
    
            // Fetch data from the network
            fetchGoodsData();
        }
    
        private void fetchGoodsData() {
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        OkHttpClient client = new OkHttpClient();
                        Request request = new Request.Builder()
                                .url("http://10.0.2.2:8080/goods/goods_list_data.json")
                                .build();
                        Response response = client.newCall(request).execute();
                        if (response.isSuccessful()) {
                            String jsonData = response.body().string();
                            Log.d("Network", "Data fetched successfully: " + jsonData);
    
                            Gson gson = new Gson();
                            Goods[] goodsArray = gson.fromJson(jsonData, Goods[].class);
    
                            // 补全图片URL
                            for (Goods goods : goodsArray) {
                                goods.setGoodsPic("http://10.0.2.2:8080//goods" + goods.getGoodsPic());
                            }
    
                            goodsList = Arrays.asList(goodsArray);
                            msgHandler.sendEmptyMessage(MSG_UPDATE_DATA);
    
                            // 切换到主线程以更新UI
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    // 设置RecyclerView的适配器
                                    adapter = new GoodsAdapter(MainActivity.this, goodsList);
                                    recyclerView.setAdapter(adapter);
                                }
                            });
    
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        Log.e("Network", "Error fetching data: " + e.getMessage());
                    }
                }
            }).start();
        }
    }
    
    
    
    • 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
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    替换"URL_TO_YOUR_JSON_DATA"为你的本地JSON文件的路径,例如:http://localhost:8080/goods/goods_list_data.json

    注意,如果你是本地部署的tomcat,需要在Android默认的虚拟器中访问,需要改为“10.0.2.2

    以下是对代码的一些说明:

    1. fetchGoodsData() 方法中创建了一个新的线程来执行网络请求。这是一个良好的实践,因为它确保网络请求不会阻塞主线程,以避免应用的响应性问题。

    2. 在网络请求成功后使用 Gson 库将 JSON 数据解析为 Goods 对象的数组,并补全了图片的URL。这确保了 Glide 能够正确加载图片。

    3. 使用 Handler 来更新UI,因为 UI更新必须在主线程中执行

    4. 在网络请求失败时,通过 Log.e 打印了错误消息,这有助于调试和问题排查。

    实现效果
    在这里插入图片描述

  • 相关阅读:
    hive中 count结果和spark sql中count结果不一致
    MySQL锁机制
    20220719_Filter_Listener_AJAX_Axios的用法
    华为数通方向HCIP-DataCom H12-831题库(单选题:301-310)
    电商项目高级篇-02 elasticsearch-下
    ContentServiceImpl
    神经网络中的Heloo,World,基于MINST数据集的LeNet
    2023 年KPI (KPI:Key Performance Indicator) review
    所有产品都值得用AI再做一遍,让AGI与品牌营销双向奔赴
    痞子衡嵌入式:瑞萨RA8系列高性能MCU开发初体验
  • 原文地址:https://blog.csdn.net/qq_22841387/article/details/133995154