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进行下载 点击之后会出现一个对话框 同意之后下载。(记住下载到哪,打…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
