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
其中,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"}
]
启动tomcat后,可访问http://localhost:8080/goods/goods_list_data.json展示信息

2.创建项目
- 打开Android Studio,并创建一个新的Android项目。
- 命名项目并选择适当的目标API级别和设备类型。
- 创建一个新的空白活动(Empty Activity)。
3.在AndroidManifest.xml中声明网络权限
在 AndroidManifest.xml 文件中添加以下权限声明,以便应用可以访问网络:
<uses-permission android:name="android.permission.INTERNET" />
由于网络安全策略导致的问题,即不允许在明文(非加密)的情况下与 localhost 进行通信。这通常涉及到网络安全配置,特别是在 Android 9.0(API级别28)及更高版本中引入了更严格的网络安全策略;因此我们还需要进行配置网络安全配置文件
解决此问题的方法之一是使用 HTTPS 协议而不是 HTTP,因为 HTTPS 是加密的。
如果在本地测试应用,可以使用 Android 的网络安全配置文件来允许明文通信。
- 在
res/xml文件夹中创建一个名为network_security_config.xml的网络安全配置文件。如果该文件夹不存在,请手动创建。
<?xml version="1.0" encoding="utf-8"?>
<network-security-config><base-config cleartextTrafficPermitted="true"><trust-anchors><certificates src="system" /><certificates src="user" /></trust-anchors></base-config>
</network-security-config>

- 在
AndroidManifest.xml文件中,将这个网络安全配置文件应用于你的应用。在<application>元素内添加android:networkSecurityConfig属性,如下所示:
<applicationandroid:networkSecurityConfig="@xml/network_security_config"<!-- 其他属性和元素 -->><!-- 其他元素 -->
</application>

这将允许你的应用在本地开发和测试过程中与 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")

进行同步

等待安装依赖……
5.创建一个XML布局文件
在res/layout文件夹中创建一个布局文件,例如activity_main.xml,用于显示商品数据。
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerViewxmlns: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"/>

创建一个XML布局文件用于显示商品项
在res/layout文件夹中创建一个布局文件,例如item_goods.xml,用于显示每个商品项。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:padding="16dp"><ImageViewandroid:id="@+id/goodsImageView"android:layout_width="100dp"android:layout_height="100dp"android:scaleType="centerCrop" /><TextViewandroid:id="@+id/goodsNameTextView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="8dp" />
</LinearLayout>

6.创建一个Java Bean类
创建一个Goods类,用于表示商品数据。
public class Goods {private int id;private String count;private String goodsName;private String goodsPic;// Getters and setters
}
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;}@Overridepublic ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_goods, parent, false);return new ViewHolder(view);}@Overridepublic void onBindViewHolder(ViewHolder holder, int position) {Goods goods = goodsList.get(position);holder.goodsNameTextView.setText(goods.getGoodsName());// Load and display image using GlideGlide.with(context).load(goods.getGoodsPic()).into(holder.goodsImageView);}@Overridepublic 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);}}
}
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() {@Overridepublic boolean handleMessage(Message msg) {if (msg.what == MSG_UPDATE_DATA) {adapter.notifyDataSetChanged();}return true;}});@Overrideprotected 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 networkfetchGoodsData();}private void fetchGoodsData() {new Thread(new Runnable() {@Overridepublic 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);// 补全图片URLfor (Goods goods : goodsArray) {goods.setGoodsPic("http://10.0.2.2:8080//goods" + goods.getGoodsPic());}goodsList = Arrays.asList(goodsArray);msgHandler.sendEmptyMessage(MSG_UPDATE_DATA);// 切换到主线程以更新UIrunOnUiThread(new Runnable() {@Overridepublic 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();}
}
替换"URL_TO_YOUR_JSON_DATA"为你的本地JSON文件的路径,例如:http://localhost:8080/goods/goods_list_data.json。
注意,如果你是本地部署的tomcat,需要在Android默认的虚拟器中访问,需要改为“
10.0.2.2”
以下是对代码的一些说明:
-
在
fetchGoodsData()方法中创建了一个新的线程来执行网络请求。这是一个良好的实践,因为它确保网络请求不会阻塞主线程,以避免应用的响应性问题。 -
在网络请求成功后使用 Gson 库将 JSON 数据解析为
Goods对象的数组,并补全了图片的URL。这确保了 Glide 能够正确加载图片。 -
使用
Handler来更新UI,因为 UI更新必须在主线程中执行。 -
在网络请求失败时,通过
Log.e打印了错误消息,这有助于调试和问题排查。
实现效果

相关文章:
Android应用:实现网络加载商品数据【OKHttp、Glide、Gson】
实现网络加载商品数据的功能: 1、在AndroidManifest.xml中声明网络权限; 2、在app/build.gradle中添加okhttp, glide, gson等必需的第3方库; 3、在MainActivity中通过OkHttpClient连接给定的Web服务,获取商品数据;对…...
增强常见问题解答搜索引擎:在 Elasticsearch 中利用 KNN 的力量
在快速准确的信息检索至关重要的时代,开发强大的搜索引擎至关重要。 随着大型语言模型和信息检索架构(如 RAG)的出现,在现代软件系统中利用文本表示(向量/嵌入)和向量数据库已变得越来越流行。 在本文中&am…...
常见网络攻击及防御方法总结(XSS、SQL注入、CSRF攻击)
网络攻击无时无刻不存在,其中XSS攻击和SQL注入攻击是网站应用攻击的最主要的两种手段,全球大约70%的网站应用攻击都来自XSS攻击和SQL注入攻击。此外,常用的网站应用攻击还包括CSRF、Session劫持等。 1、 XSS攻击 XSS攻击即跨站点脚本攻击&am…...
python爬虫request和BeautifulSoup使用
request使用 1.安装request pip install request2.引入库 import requests3.编写代码 发送请求 我们通过以下代码可以打开豆瓣top250的网站 response requests.get(f"https://movie.douban.com/top250")但因为该网站加入了反爬机制,所以…...
记录--vue3实现excel文件预览和打印
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前言 在前端开发中,有时候一些业务场景中,我们有需求要去实现excel的预览和打印功能,本文在vue3中如何实现Excel文件的预览和打印。 预览excel 关于实现excel文档在…...
消息队列中间件面试笔记总结RabbitMQ,Kafka,RocketMQ
文章目录 (一) Rabbit MQRabbitMQ 核心概念消息队列的作用Exchange(交换器)Broker(消息中间件的服务节点)如何保证消息的可靠性如何保证 RabbitMQ 消息的顺序性如何保证 RabbitMQ 高可用的?如何解决消息队列的延时以及过期失效问题消息堆积问…...
pycharm远程连接Linux服务器
文章目录 一:说明二:系统三:实现远程连接方式一: 直接连接服务器不使用服务器的虚拟环境步骤一:找到配置服务器的地方步骤二:进行连接配置步骤三:进行项目文件映射操作步骤四:让文件…...
Android应用开发(38)全屏显示隐藏状态栏和导航栏
Android应用开发学习笔记——目录索引 protected void onCreate(Bundle savedInstanceState) {/* 添加代码 */requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);WindowManager.LayoutParams lp ge…...
日本IT Week秋季展丨美格智能以技术创新共建美好数字生活
10月25日至27日,日本国际IT消费电子展览会(Japan IT Week 2023秋季展)在日本千叶幕张国际展览中心举行。日本IT周是日本IT市场的标杆,涵盖软件开发、大数据管理、嵌入式系统、数据存储、信息安全、数据中心、云计算、物联网&#…...
centos7 install postgres-15
env centos7 1.更新包,避免安装时出错 yum update 2. PostgreSQL: Linux downloads (Red Hat family) sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm sudo yum install -y post…...
JVM常见的垃圾回收器(详细)
1、Young为年轻代出发的垃圾回收器。 2、Old为老触发的垃圾回收器。 3、连线代表的是垃圾回收器的组合。CMS 和Serial Old连线代表CMS一旦不行了,Serial Old上场。 首先了解一个概念:STW 1、什么是STW? STW是Stop-The-World缩写: 是在垃圾回…...
acwing 5283. 牛棚入住
题目 - 点击直达 1. 5283. 牛棚入住1. 题目详情1. 原题链接2. 题目要求3. 基础框架 2. 解题思路1. 思路分析2. 时间复杂度3. 代码实现 1. 5283. 牛棚入住 1. 题目详情 贝茜经营的牛棚旅店中有 a 个可供一头牛入住的小牛栏和 b 个可供两头牛入住的大牛栏。 初始时,…...
Qt触摸屏双指缩放和单指移动界面(支持嵌入式设备)
本文介绍的QGraphicsView的双指缩放,QWidget更简单,可以参考当前内容。 方法一:(QTouchEvent事件实现) 使用场景:适用于paintevent绘制下的界面。 优点:不需要代码设置中心锚点(锚点…...
【Linux】虚拟机安装Linux、客户端工具,MobaXterm的使用,Linux常用命令
目录 一,安装Linux的centos7版本 具体安装步骤: 二,Linux常见的命令: 三、安装客户端工具 1、介绍 2、安装MobaXterm 3、换源 四、拍照功能 一,安装Linux的centos7版本 介绍: 具体安装步骤&#…...
springboot-scanBasePackages包扫描
目录 原因: 方式一: 方式二: 原因: 由于对rocketMq进行了一次封装,mq模块里面引用了RocketMQTemplate的bean,如果只引入jar包的依赖,启动的时候不会报错,但是在调用到 RocketMQT…...
【C语言数据结构——————排序(1万字)】
文章目录 排序的概念 常见排序算法分类冒泡排序 时间复杂度稳定性 原理实现插入排序 时间复杂度稳定性实现选择排序 时间复杂度稳定性实现希尔排序 时间复杂度稳定性希尔排序的算法思想实现 优化快速排序 时间复杂度空间复杂度稳定性实现 三数取中优化归并排序 时间复杂度空间复…...
PyTorch基础(18)-- torch.stack()方法
一、方法详解 首先,看一下stack的直观解释,动词可以简单理解为:把……放成一堆、把……放成一摞。 有了对stack方法的直观感受,接下来,我们正式解析torch.stack方法。 PyTorch torch.stack() method joins (concaten…...
从lc560“和为 K 的子数组“带你认识“前缀和+哈希表“的解题思路
1 前缀和哈希表解题的几道题目:建议集中练习 560. 和为 K 的子数组:https://leetcode.cn/problems/subarray-sum-equals-k/ 1248. 统计「优美子数组」: https://leetcode.cn/problems/count-number-of-nice-subarrays/ 1249. 和可被 K 整除的子数组(利用…...
c:变参函数:汇编解析;va_list;marco 宏:__VA_ARGS__
文章目录 参考gcc 内部的宏定义代码汇编调用在 SEI CERT C Coding Standard 这个标准里示例实例宏里的使用 参考 https://git.sr.ht/~gregkh/presentation-security/blob/3547183843399d693c35b502cf4a313e256d0dd8/security-stuff.pdf gcc 内部的宏定义 宏定义:…...
eclipse安装教程(2021版)
第一步:下载JDK (下载地址) Java SE - Downloads 第二步 根据自己电脑的系统,选择相应的版本x64代表64位,x86代表32位。点击相应的JDK进行下载 点击之后会出现一个对话框 同意之后下载。(记住下载到哪,打…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
DiscuzX3.5发帖json api
参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...
