Android项目实战开发-----期末总结2

项目三:网络层和数据模型的封装

任务一:网络请求和数据解析

1,网络请求

(1)Android中的网络存储主要是使用HTTP/HTTPS协议访问服务器,与服务器发生数据交互。

(2)Android提供两种执行HTTP请求的方式:

  • ​ HttpClient请求(有bugs,API23已经被弃用)​ HttpURLConnection请求

HttpUrlConnection执行http Get请求核心代码:

 public class PostUtils {public static String LOGIN_URL = "填URL地址";
​public static String LoginByPost(String number, String passwd) {String msg = "";try {HttpURLConnection conn = (HttpURLConnection) new URL(LOGIN_URL).openConnection();// 设置请求方式,请求超时信息conn.setRequestMethod("POST");conn.setReadTimeout(5000);conn.setConnectTimeout(5000);// 设置运行输入,输出:conn.setDoOutput(true);conn.setDoInput(true);// Post方式不能缓存,需手动设置为falseconn.setUseCaches(false);// 我们请求的数据:String data = "passwd=" + URLEncoder.encode(passwd, "UTF-8") + "&number=" + URLEncoder.encode(number, "UTF-8");// 这里可以写一些请求头的东东...// 获取输出流OutputStream out = conn.getOutputStream();out.write(data.getBytes());out.flush();if (conn.getResponseCode() == 200) {// 获取响应的输入流对象InputStream is = conn.getInputStream();// 创建字节输出流对象ByteArrayOutputStream message = new ByteArrayOutputStream();// 定义读取的长度int len = 0;// 定义缓冲区byte buffer[] = new byte[1024];// 按照缓冲区的大小,循环读取while ((len = is.read(buffer)) != -1) {// 根据读取的长度写入到os对象中message.write(buffer, 0, len);}// 释放资源is.close();message.close();// 返回字符串msg = new String(message.toByteArray());return msg;}} catch (Exception e) {e.printStackTrace();}return msg;}
}

(3)使用OKhttp框架进行网络请求(基于HttpURLConnection进行封装)

OKhttp可以实现的功能:

  • get/post同步,异步请求

  • HTTPS安全证书形式的网络请求

  • 文件上传和下载

  • 图片加载

  • 支持请求回调,直接返回对象或者对象的集合

  • 支持session的保存

OKhttp的特点:

  • Http/2支持多路复用

  • 采用连接池减少请求延时

  • 支持GZIP压缩

  • 相应缓存

  • 支持websocket

  • 多IP切换(连接失败并且服务器有多IP)

OKhttp的使用

使用OKhttp执行 GET请求的使用步骤

  • 第一步:新建一个OkhttpClient对象,这个对象最好在整个APP中只有一个实例存在。

  • 第二步:新建一个Request请求对象,它使用Builder的方式进行创建,需要包含请求的接口URL

  • 第三步:使用OkhttpClient对象新建一个Call请求,并传入Request对象

  • 第四步:将Call加入请求队列,执行该请求

示例核心代码:

   
 /*** OkHttp 异步 Get 请求*/private void httpAsynchronousGet() {// Request 中封装了请求相关信息Request request = new Request.Builder().url("https://www.baidu.com")   // 设置请求地址.get()                          // 使用 Get 方法.build();
​// 异步 Get 请求mOkHttpClient.newCall(request).enqueue(new Callback(){
​@Overridepublic void onFailure(Call call, IOException e) {// 请求失败的情况}
​@Overridepublic void onResponse(Call call, Response response) throws IOException {// 请求成功 , 获取String result = response.body().string();Log.i(TAG, "result : " + result);runOnUiThread(new Runnable() {@Overridepublic void run() {// 主线程中执行相关代码}});}});}

使用Okhttp执行Http POST请求的使用步骤

  • 第一步:新建一个OkhttpClient对象。

  • 第二步:使用FormBody来构建包含键值对类型参数的请求体。

  • 第三步:新建一个Request请求对象,需要包含请求的接口URL和请求体

  • 第四步:使用OkhttpClient对象新建一个Call请求,并传入Request对象

  • 第五步:将Call加入请求队列,执行该请求

示例核心代码:

    /*** OkHttp 异步 Post 请求*/private void httpAsynchronousPost() {// 创建 Post 表单 , 主要用于设置 Post 请求键值对FormBody formBody = new FormBody.Builder().add("Key", "Value").build();
​// Request 中封装了请求相关信息Request request = new Request.Builder().url("https://www.baidu.com")   // 设置请求地址.post(formBody)                 // 使用 Post 方法.build();
​// 创建异步回调Callback callback = new Callback(){
​@Overridepublic void onFailure(Call call, IOException e) {// 请求失败的情况}
​@Overridepublic void onResponse(Call call, Response response) throws IOException {// 请求成功 , 获取String result = response.body().string();Log.i(TAG, "result : " + result);runOnUiThread(new Runnable() {@Overridepublic void run() {// 主线程中执行相关代码}});}};// 异步 Get 请求mOkHttpClient.newCall(request).enqueue(callback);}

2,数据解析

(1)概述

  • 我们与服务器进行数据交互的数据格式大部分都是JSON格式(取代XML的数据结构)

  • 对JSON数据进行反序列化操作,转换成相应的对象或集合-------数据解析

  • JSON的语法(JSON本质是一种特定的字符串):“[ ]”表示数组,“{ }”表示对象,数据以键值对的进行表示。

  • JSON解析的结果有两种形式:一种是Javabean(单个对象实体类的对象);另一种是集合。它可以是List<String>,List<T>等

(2)传统的数据解析(根据JSON字符串不同,解析的方式也不同)

常见的是JSONObject(对应一个实体类的对象)和JSONArray(对应一个数组)互相嵌套使用

(3)Gson框架解析

主要提供两个方法:

​ fromJson()方法--------实现将JSON数据转换为相应的Java对象。

核心代码示例:

​Gson gson = new Gson();String personTest = gson.toJson(p);
​

​ toJson()方法-----------实现将Java对象转换为相对应的JSON数据。

​
Person person = gson.fromJson(personTest, Person.class);
System.out.println(person);

Gson框架的优点:

​ 实现Java对象和JSON之间的互相转换。

​ 允许已经存在的无法改变的对象,转换成JSON,或者JSON转换成已存在的对象。

​ 允许自定义对象的表现形式。

​ 支持任意的复杂对象。

​ 能够生成可压缩和可读的JSON的字符串输出。

Gson框架使用关键:

​ 推荐把成员变量都声明成private修饰。

​ 如果某个字段被transient关键词修饰,就不会被序列化或者反序列化。

​ 当序列化的时候,如果对象的某个字段为null,是不会输出到JSON字符串中的。

​ 当反序列化的时候,某个字段在JSON字符串中找不到对应的值,就会被赋值为null。

​ 当内部类的某个字段和外部类的某个字段一样的话,就会被忽视,不会被序列化或者反序列化。

Gson框架的使用示例:(略)

任务二:数据模型的封装

1,理解MVP架构模式

MVP是传统MVC架构模式的扩展。使用MVC架构模式,开发者常会遇到以下困难:

  • 大部分的核心业务逻辑放在Controller中,在应用程序的整个生命周期内,这个文件会变得越来越大,越来越难维护。

  • 由于UI和业务逻辑的紧密耦合,Controller层和View层都将属于同一个activity或fragment。这将导致在更改应用程序功能时出现问题。

  • 由于大多数测试的部分依赖Android SDK组件,因此针对不同层执行单元测试时变得困难了。

MVP模式克服了MVC模式的这些挑战,并且提供了一种简单的方法来构造项目代码。MVP模式之所以被广泛接受,因为它提供了模块化、可测试以及更干净和更易于维护的代码基准。它由以下三部分组成:

  • Model:用于存储数据。它负责处理领域逻辑以及与数据库或网络层的通信。

  • View:UI层,提供数据可视化界面,并跟踪用户的操作,以便通知presenter。

  • Presenter:从Model层获取数据,并且应用UI逻辑来决定显示什么。它管理View的状态,并且根据来自于View的用户的输入执行动作。

mvp架构要点

  1. View和Presenter以及Presenter和Model之间通过接口(也称为contract)通信。

  2. 一个Presenter管理一个View,即:presenter和view是一对一的关系。

  3. Model和View之间无关联。

2,数据模型的封装(略)

3,引入greenDao数据库框架

(1)用于生成数据库代码

任务三:网络框架的封装

1,Retrofit概述(Retrofit将您的HTTP API转换为Java接口;Retrofit 是一个 RESTful 的 HTTP网络请求框架的封装,网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责网络请求接口的封装;)

(1)Square公司非常严格的RestFul客户端库,采用注解来描述HTTP请求,默认会集成URL参数替换。

(2)提供了自定义头信息,多请求体,文件上传下载,模拟响应等

(3)基本包含Okhttp库的所以特性和功能。

(4)引入

(5)使用说明

1,引用,在gradle文件中引用retrofit2、定义接口,Retrofit要求定义一个网络请求的接口,接口函数里要定义url路径、请求参数、返回类型。3、依次获得Retrofit对象、接口实例对象、网络工作对象 首先,需要新建一个retrofit对象。

​ 然后,根据上一步的接口,实现一个retrofit加工过的接口对象。

​ 最后,调用接口函数,得到一个可以执行网络访问的网络工作对象。

4、访问网络数据,用上一步获取的worker对象,执行网络请求,在回调函数里,取得我们需要的BizEntity数据对象。网络访问结束。

2,RxJava

(1)概述

​ 1)是一个在Java VM上使用可观测的序列化来组成异步的,基于事件的程序的库。

​ 2)质就是一个实现异步操作的库,异步操作的实现通过一种可扩展的观察者模式。

​ 3)RxJava的观察者模式主要有四个概念:

  • 被观察者:Observable,相当于Button。

  • 观察者:Observer,相当于onClickListener

  • 订阅:subscribe,相当于setOnClickListener。

  • 事件:普通事件onNext(),相当于onClick;

    4)它还有一些事件:onCompleted()/onError()/onStart()

2,引入()

1、引入 RxJava 依赖

Gradle 项目中 , 在 build.gradle 构建脚本中 , 添加如下依赖 ;

dependencies {implementation 'io.reactivex.rxjava2:rxjava:2.2.21'
}

rxjava3 依赖 :

dependencies {implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
}
​

3,使用说明

1、定义 Observer 观察者

Observer(观察者): Observer 表示一个接收 Observable 发送消息 的观察者。 它可以处理从 Observable 发射的消息, 还可以处理错误和完成的事件。

Observer 观察者 是 操作的核心 , 定义在需要进行具体操作的位置 , 执行具体的 异步操作 或 事件 ;

如 : 在 UI 界面中 , 点击按钮 , 查询远程数据库服务器中的数据 , 查询完毕后更新 UI 界面 ;

该 Observer 观察者 就需要 定义在 UI 界面中 , 可以获取到相关的 UI 组件进行数据更新 ;Observable 被观察者可以定义在 Observer 观察者位置 , 也可以定义在消息发送的位置 , 这里 推荐定义在消息发送的位置 ;调用时 , 将 Observer 观察者 传递给对应的异步操作函数 ;在异步操作函数中 , 创建 Observable 被观察者 , 并且通过订阅将观察者订阅到被观察者中 ;订阅操作 , 就会同时发送消息给 观察者 ;

Observer 观察者定义代码 :

Observer<String> observer = new Observer<String>() {@Overridepublic void onSubscribe(Disposable d) {// 当观察者订阅时的回调}
​@Overridepublic void onNext(String value) {// 当接收到新的事件时的回调System.out.println(value);}
​@Overridepublic void onError(Throwable e) {// 当发生错误时的回调}
​@Overridepublic void onComplete() {// 当事件流结束时的回调}
};

2、定义 Observable 被观察者

Observable(被观察者): Observable 是一个 可以发送消息的数据源 , 可以同时发送若干消息 , 消息的格式可以通过泛型进行定义 ; 消息发送完毕后 会 通知观察者。Observable 通过 订阅观察者 来实现 消息的传递。

Observable<String> observable = Observable.just("Hello", "World");

3、Observable 被观察者订阅 Observer 观察者

Subscription(订阅): 订阅是 Observer 对 Observable 的绑定, 它表示观察者正在接收 Observable 的数据项。 订阅可以被取消, 取消订阅后 Observer 观察者将不再接收 Observable 被观察者 的消息。

调用 Observable 被观察者 的 subscribe 函数 , 订阅 Observer 观察者 ;

该订阅操作的同时 , 会将消息发送给 Observer 观察者 , 触发 Observer#onNext 函数 ;

observable.subscribe(observer);

二、代码示例

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
​
public class Main {public static void main(String[] args) {Observable<String> observable = Observable.just("Hello", "World", "RxJava");
​Observer<String> observer = new Observer<String>() {@Overridepublic void onSubscribe(Disposable d) {// 当观察者订阅时的回调}
​@Overridepublic void onNext(String value) {// 当接收到新的事件时的回调System.out.println(value);}
​@Overridepublic void onError(Throwable e) {// 当发生错误时的回调}
​@Overridepublic void onComplete() {// 当事件流结束时的回调}};
​observable.subscribe(observer);}
}
​

执行结果 :

Hello
World
RxJava

4,线程控制(略)

5,变换(略)

Retrofit与RxJava的联合封装

1,封装后的网络请求示意图

2,引入(略)

3,封装的公共部分(略)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/182692.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python -- python安装

1、python的诞生和发展&#xff1a; python语言是一种解释型、面向对象型、动态数据类型的高级程序设计语言。 2、python的安装&#xff1a; 1、安装解析器&#xff1a; 在安装的过程中需要注意的是&#xff1a; 在安装pycharm的时候也是同样的道理&#xff0c;需要指定安装…

【长文干货】Python可视化教程

文章目录 数据介绍Matplotlib散点图折线图柱形图直方图 Seaborn散点图折线图柱形图直方图 Bokeh散点图折线条形图交互式 Plotly基本组合优化&#xff1a;定制化下拉菜单 总结 数据介绍 在这个小费数据集中&#xff0c;我们记录了20世纪90年代初期餐厅顾客在两个半月内给出的小…

【机器学习 | 可视化】回归可视化方案

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

LESS的叶绿素荧光模拟实现——任意波段荧光模拟

目录 前言一、任意波段荧光模拟的实现二、需要注意的输入参数 前言 此专栏默认您对LESS (LargE-Scale remote sensing data and image Simulation framework) 模型和叶绿素荧光(Sun-Induced chlorophyll Fluorescence, SIF)有一定的了解。当然&#xff0c;您也可以在这里下载中…

Kubernetes

Kubernetes Docker的安装Docker安装&#xff1a;安装docker依赖环境配置国内docker-ce的yum源&#xff08;这里采用的是阿里云&#xff09;安装docker。插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自…

C++基础 -17-继承中 基类与派生构造和析构调用顺序

首先声明 定义了派生类会同时调用基类和派生的构造函数 定义了派生类会同时调用基类和派生的析构函数 那么顺序如何如下图 构造由上往下顺序执行 析构则完全相反 #include "iostream"using namespace std;class base {public:base(){cout << "base-bui…

orvibo旗下的VS30ZW网关分析之二:版本回退方法

概述 上接第一篇: orvibo旗下的VS30ZW网关分析之一-CSDN博客 此产品VS30ZW支持openwrt的页面,可以版本回退进行刷机。 openwrt固件下载: 固件名称:openwrt-VS30ZW-mt7628.bin 链接地址:https://download.csdn.net/download/leekwen/88579427 版本回退方法: 1、同…

多模态大模型总结2(主要2023年)

LLaVA-V1&#xff08;2023/04&#xff09; 论文&#xff1a;Visual Instruction Tuning 网络结构 如下图 所示为 LLaVA-v1 的模型结构&#xff0c;可以看出其简化了很多&#xff0c;但整体来说还是由三个组件构成&#xff1a; Vision Encoder&#xff1a;和 Flamingo 模型的 V…

微信小程序获取手机号上限,怎么处理比较省钱

微信新规 微信2023年改了规则&#xff0c;原本免费的小程序获取手机号&#xff0c;现在如果要获取要1分钱一条。 有些小程序的用户非常恐怖&#xff0c; 比如一些工具类的&#xff0c; 群发类的。如果进入小程序就必须要获取小程序&#xff0c;就像是无底洞&#xff0c;让运营…

【古月居《ros入门21讲》学习笔记】14_参数的使用与编程方法

目录 说明&#xff1a; 1. 参数模型&#xff08;全局字典&#xff09; 2. 实现过程&#xff08;C&#xff09; 创建功能包 参数命令行的使用 YAML参数文件 rosparam命令 使用示例 编程方法&#xff08;C&#xff09; 配置代码编译规则 编译并运行 编译 运行 3. 实…

【C++笔记】红黑树的简易实现

【C笔记】红黑树的简易实现 一、什么是红黑树以及红黑树好在哪里1.1、什么是红黑树1.2、红黑树比AVL树好在哪里&#xff1f; 二、红黑树的模拟实现2.1、红黑树的插入2.2、仅变色调整2.3、变色单旋调整2.4、变色双旋调整 一、什么是红黑树以及红黑树好在哪里 1.1、什么是红黑树…

Docker容器网络模式

1.none网络 1&#xff09;使用默认网络模式创建一个BusyBox容器&#xff0c;用于对比none网络模式&#xff1b; 测试网络&#xff0c;可以正常连接外网。 2&#xff09;再创建一个none网络模式的BusyBox容器&#xff1b; 测试网络连接&#xff0c;无法连接外网。 总结&#x…

深入了解Spring Boot中@Async注解的8大坑点

文章目录 1. 缺少EnableAsync注解2. 异步方法需独立3. 不同的异步方法间无法相互调用4. 返回值为void的异步方法无法捕获异常5. 外部无法直接调用带有Async注解的方法6. Async方法不适用于private方法7. 缺失异步线程池配置8. 异步方法与事务的兼容结语 &#x1f389;深入了解S…

Ros报错:The Plugin for class ‘jsk_rviz_plugin/Plotter2D‘ failed to load

一般出现这种情况&#xff0c;是提醒Ros缺少某种库&#xff1a; 图中显示的错误是说明少了jsk_rviz_plugins库&#xff0c;他是一个提供原始rviz插件的包。 解决办法是安装相应的库与插件&#xff1a; #根据自己ROS的版本选择相应的指令 # ubuntu20.04:noetic sudo apt-get i…

RabbitMQ消息的应答

消息的应答机制 消费者完成一个任务可能需要一段时间&#xff0c;如果其中一个消费者处理一个长的任务并仅只完成了部分突然它挂掉了&#xff0c;会发生什么情况。RabbitMQ 一旦向消费者传递了一条消息&#xff0c;便立即将该消息标记为删除。在这种情况下&#xff0c;突然有个…

计算机视觉:使用dlib实现人脸检测

1 dlib介绍 Dlib是一个广泛使用的开源库&#xff0c;在计算机视觉和机器学习领域具有重要影响。它是由Davis King在2002年开发&#xff0c;主要用C语言编写&#xff0c;但也提供了Python接口。Dlib结合了高效的算法和易用性&#xff0c;使其成为学术界和工业界的热门选择。 1.…

SpringBoot项目启动后自动停止了?

1 现象 2023-11-22T09:05:13.36108:00 DEBUG 17521 --- [ main] o.s.b.a.ApplicationAvailabilityBean : Application availability state LivenessState changed to CORRECT 2023-11-22T09:05:13.36208:00 DEBUG 17521 --- [ main] o.s.b.a.Applicat…

一文1000字彻底搞懂Web测试与App测试的区别

总结分享一些项目需要结合Web测试和App测试的工作经验给大家&#xff1a; 从功能测试区分&#xff0c;Web测试与App测试在测试用例设计和测试流程上没什么区别。 而两者的主要区别体现在如下几个方面&#xff1a; 1 系统结构方面 Web项目&#xff0c;B/S架构&#xff0c;基…

Android中实现RecyclerView,并对item及其多个子控件的点击事件监听

目录 背景 实现RecyclerView 第一步、 新建item的xml 第二步、在activity的布局中引入 RecyclerView 第三步、新建一个adapter 第四步、在activity中初始化绑定adapter即可 实现item及其多个子组件点击事件监听 第一步、 适配器中创建监听对象 第二步、适配器中绑定监听…

uniapp ios 授权弹窗 uniapp弹出框怎么实现

新版本的信息弹窗组件 可以弹出很多条信息&#xff0c;并单独控制消失时间、点击消失。 用循环来生成很多个弹窗&#xff0c;用this.$refs来传值&#xff0c;并添加数组。 1.布局 2.js 具体流程。需要一个弹窗&#xff0c;基本信息传入组件&#xff0c;处理后添加入数组&am…