【Android】网络技术知识总结之WebView,HttpURLConnection,OKHttp,XML的pull解析方式

文章目录

  • webView
    • 使用步骤
    • 示例
  • HttpURLConnection
    • 使用步骤
    • 示例
    • GET请求
    • POST请求
  • okHttp
    • 使用步骤
    • 1. 添加依赖
    • 2. 创建OkHttpClient实例
    • 3. 创建Request对象构建请求
    • 4. 发送请求
    • 5. 获取响应
  • Pull解析方式
    • 1. 准备XML数据
    • 2. 创建数据类
    • 3. 使用Pull解析器解析XML

webView

WebView 是 Android 中用于显示网页内容的组件。它允许你在应用内嵌入一个浏览器,加载并显示 HTML、JavaScript、CSS 等网页内容。以下是使用 WebView 的步骤和一些示例代码。

使用步骤

  1. 在布局文件中添加 WebView

    • 在 XML 布局文件中定义一个 WebView 控件。
  2. 在 Activity 或 Fragment 中初始化 WebView

    • 获取布局中的 WebView 实例,并配置其设置。
  3. 加载网页内容

    • 使用 loadUrl() 方法加载网页 URL,或使用 loadData() 方法加载 HTML 字符串。
  4. 配置设置(可选)

    • 配置 JavaScript 支持、缓存设置等。
  5. 处理 WebView 的事件(可选)

    • 设置 WebViewClientWebChromeClient 来处理网页加载过程中的事件和 JavaScript 对话框。
  6. 权限

    AndroidManifest.xml 中添加互联网权限:

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

示例

  1. 布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><WebViewandroid:id="@+id/webview"android:layout_width="match_parent"android:layout_height="match_parent" />
</RelativeLayout>
  1. 在 Activity 中使用 WebView

MainActivity.java 中初始化并使用 WebView

import android.os.Bundle;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private WebView webView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);webView = findViewById(R.id.webview);// 启用 JavaScript 支持webView.getSettings().setJavaScriptEnabled(true);// 设置 WebViewClient 以处理网页加载事件webView.setWebViewClient(new WebViewClient());// 加载网页内容webView.loadUrl("https://www.baidu.com");}
}

配置 WebView 设置

  • JavaScript 支持:启用 JavaScript 支持以处理动态网页内容。

    webView.getSettings().setJavaScriptEnabled(true);
    
  • 缓存设置:可以设置缓存模式来优化加载速度。

    webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
    
  • 自定义用户代理:可以设置用户代理字符串。

    webView.getSettings().setUserAgentString("Custom User Agent");
    

处理 WebView 事件

  • WebViewClient:用于处理网页加载过程中的事件。
    • onPageStarted(WebView view, String url, Bitmap favicon):当页面开始加载时调用。
    • onPageFinished(WebView view, String url):当页面加载完成时调用。
    • shouldOverrideUrlLoading(WebView view, WebResourceRequest request):处理 URL 跳转请求。

权限

AndroidManifest.xml 中添加互联网权限:

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

HttpURLConnection

HttpURLConnection 是 Android 中用于处理 HTTP 请求的类。它提供了一种在应用中发送和接收 HTTP 请求和响应的方法。

使用步骤

1. 创建 URL 对象

  • 使用指定的 URL 创建 URL 对象。

2. 打开连接

  • 使用 URL.openConnection() 打开连接,并将其转换为 HttpURLConnection

3. 配置连接参数

  • 设置请求方法(如 GET 或 POST)。
  • 配置连接和读取超时时间等参数。

4. 发送请求

  • 获取输入流并读取服务器响应。

5. 处理响应

  • 读取输入流中的数据,并进行处理。

6. 关闭连接

  • 关闭输入流和断开连接。
// 创建一个URL对象,指定请求的URL地址
URL url = new URL("http://www.baidu.com");
// 打开一个到该URL的HTTP连接,并将其转换为HttpURLConnection
HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 设置请求方法为GET
connection.setRequestMethod("GET");
// 设置连接超时时间为8秒
connection.setConnectTimeout(8000);
// 设置读取超时时间为8秒
connection.setReadTimeout(8000);// 获取服务器响应的输入流
InputStream inputStream = connection.getInputStream();
// 字节流->字符流->字符缓冲流
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {sb.append(line);
}
return sb.toString();
// 断开与服务器的连接
connection.disconnect();

示例

获取百度网页源码

Android 9.0(API level 28)及更高版本中,对所有的网络请求必须使用HTTPS

public class MainActivity extends AppCompatActivity implements View.OnClickListener {// 显示服务器响应的文本视图private TextView tv;// 发送请求的按钮private Button button;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);button = findViewById(R.id.btn_send);tv = findViewById(R.id.tv_response);button.setOnClickListener(this);}@Overridepublic void onClick(View v) {// 在新线程中执行网络请求new Thread(new Runnable() {@Overridepublic void run() {// 初始化HTTP连接和读取器HttpURLConnection connection = null;BufferedReader reader = null;try {// 创建URL对象,指定请求的URLURL url = new URL("https://www.baidu.com");// 打开连接connection = (HttpURLConnection) url.openConnection();// 设置请求方法为GETconnection.setRequestMethod("GET");// 设置连接超时和读取超时时间connection.setConnectTimeout(8000);connection.setReadTimeout(8000);// 获取输入流,用于读取服务器响应InputStream inputStream = connection.getInputStream();// 将输入流包装为缓冲读取器reader = new BufferedReader(new InputStreamReader(inputStream));StringBuilder sb = new StringBuilder();String line;while ((line = reader.readLine()) != null) {sb.append(line);}// 在UI线程中更新界面showResponse(sb.toString());} catch (IOException e) {throw new RuntimeException(e);} finally {if (reader != null) {try {reader.close();} catch (IOException e) {throw new RuntimeException(e);}}if (connection != null)connection.disconnect();}}}).start();}// 在UI线程中更新响应文本private void showResponse(final String string) {runOnUiThread(new Runnable() {@Overridepublic void run() {tv.setText(string);}});}
}

申请权限

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

GET请求

主要目的:从服务端获取符合条件的数据。

image-20240806201410364

POST请求

主要目的:向服务端提交数据。

场景举例:用户注册的时候,填写表格里一堆的信息(姓名、性别、年龄、电话…),这些都是要提交给服务端的数据

表单

image-20240806201938856

image-20240806203014879

okHttp

使用步骤

1. 添加依赖

implementation 'com.squareup.okhttp3:okhttp:4.10.0'

2. 创建OkHttpClient实例

OkHttpClient client = new OkHttpClient();

这是进行网络请求的客户端,配置了连接池、超时设置等参数。

3. 创建Request对象构建请求

Request request = new Request.Builder().url("https://www.baidu.com").build();

使用 Request.Builder 来构建 HTTP 请求,包括设置 URL 和请求方法(GET、POST 等)。

4. 发送请求

调用execute方法发送请求并获取服务器返回数据

Response response = client.newCall(request).execute();

newCall(request).execute() 会同步地执行请求,并返回一个 Response 对象。异步执行可以使用 enqueue 方法。

5. 获取响应

final String responseData = response.body().string();

Response 对象中获取响应体,并将其转为字符串。响应体只能读取一次,所以多次使用它,可能需要将其保存到其他地方。

更新 UI

runOnUiThread(new Runnable() {@Overridepublic void run() {tv.setText(responseData);}
});

由于网络请求是在子线程中执行的,任何更新 UI 的操作都必须在主线程中进行。使用 runOnUiThread 来确保 UI 更新在主线程中执行。

示例

public class MainActivity extends AppCompatActivity implements View.OnClickListener {private TextView tv;      private Button button;  @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);  button = findViewById(R.id.btn_send);tv = findViewById(R.id.tv_response);button.setOnClickListener(this);}@Overridepublic void onClick(View v) {// 在子线程中进行网络请求new Thread(new Runnable() {@Overridepublic void run() {// 创建 OkHttpClient 实例OkHttpClient client = new OkHttpClient();// 构建一个 GET 请求,指定请求的 URLRequest request = new Request.Builder().url("https://www.baidu.com").build();try {// 执行网络请求,并获取响应Response response = client.newCall(request).execute();// 获取响应体的字符串形式final String responseData = response.body().string();// 使用 runOnUiThread() 确保 UI 更新在主线程中进行runOnUiThread(new Runnable() {@Overridepublic void run() {// 更新 TextView 的内容为网络请求的响应数据tv.setText(responseData);}});} catch (IOException e) {// 捕获并打印可能发生的 IOExceptione.printStackTrace();}}}).start();  // 启动子线程进行网络请求}
}

Pull解析方式

Pull解析器是一种基于事件的解析方式,当解析器读取到XML文档中的开始标签、结束标签或文本内容时,会触发相应的事件。它是Android中处理XML的推荐方法之一,因其速度快且内存占用低。

1. 准备XML数据

假设我们有如下的XML数据:

<users><user><name>John Doe</name><age>30</age><married>true</married></user><user><name>Jane Doe</name><age>25</age><married>false</married></user>
</users>

2. 创建数据类

我们需要创建一个数据类来表示解析后的数据:

public class User {private String name;private int age;private boolean married;// ...
}

3. 使用Pull解析器解析XML

在Activity或Fragment中使用Pull解析器解析XML数据:

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// XML字符串String xmlData = "<users><user><name>John Doe</name><age>30</age><married>true</married></user><user><name>Jane Doe</name><age>25</age><married>false</married></user></users>";try {// 解析XMLList<User> users = parseXML(xmlData);// 遍历解析得到的用户列表并打印日志for (User user : users) {Log.d("MainActivity", "User Name: " + user.getName());Log.d("MainActivity", "User Age: " + user.getAge());Log.d("MainActivity", "User Married: " + user.isMarried());}} catch (XmlPullParserException | IOException e) {e.printStackTrace();}}// 解析XML数据private List<User> parseXML(String xmlData) throws XmlPullParserException, IOException {List<User> users = null; // 用于存储用户对象的列表User currentUser = null; // 当前正在解析的用户对象boolean insideUser = false; // 标记当前是否在<user>标签内// 创建XmlPullParserFactory和XmlPullParser实例XmlPullParserFactory factory = XmlPullParserFactory.newInstance();XmlPullParser parser = factory.newPullParser();parser.setInput(new StringReader(xmlData)); // 设置解析器的输入为XML字符串int eventType = parser.getEventType(); // 获取事件类型while (eventType != XmlPullParser.END_DOCUMENT) { // 遍历整个文档String tagName;switch (eventType) {case XmlPullParser.START_DOCUMENT:users = new ArrayList<>(); // 初始化用户列表break;case XmlPullParser.START_TAG:tagName = parser.getName(); // 获取标签名if (tagName.equals("user")) { // 如果是<user>标签insideUser = true; // 标记进入<user>标签currentUser = new User(); // 创建一个新的User对象} else if (currentUser != null) {// 仅当在<user>标签内部时,才解析这些标签if (tagName.equals("name") && insideUser) {currentUser.setName(parser.nextText());} else if (tagName.equals("age") && insideUser) {currentUser.setAge(Integer.parseInt(parser.nextText()));} else if (tagName.equals("married") && insideUser) {currentUser.setMarried(Boolean.parseBoolean(parser.nextText()));}}break;case XmlPullParser.END_TAG:tagName = parser.getName(); // 获取结束标签的名称if (tagName.equals("user") && currentUser != null) {users.add(currentUser); // 将解析完毕的用户对象添加到列表中insideUser = false; // 标记离开<user>标签}break;}eventType = parser.next(); // 获取下一个事件}return users; // 返回解析得到的用户列表}
}
  • 创建XmlPullParserFactoryXmlPullParser实例。
  • 设置解析器的输入为XML字符串。
  • 使用while循环遍历整个XML文档,根据事件类型(开始标签、结束标签、文本等)进行相应处理。
  • 在遇到<user>标签时,创建新的User对象并开始填充数据。
  • 在遇到</user>标签时,将填充完毕的User对象添加到List<User>中。
  • 解析完成后,返回包含所有用户信息的列表。


感谢您的阅读
如有错误烦请指正


参考:

  1. 31.2-Android网络请求的Get与Post方法(1)_哔哩哔哩_bilibili

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

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

相关文章

【Nacos无压力源码领读】(三) Nacos 配置中心与热更新原理详解 敢说全网最细

本文将从 Nacos 配置中心的基本使用入手, 详细介绍 Nacos 客户端发布配置, 拉取配置, 订阅配置的过程以及服务器对应的处理过程; 配置订阅以及热更新原理相关的部分, 我看了主流的博客网站, 绝对没有比这更详细的讲解; 如果在阅读过程中对文中提到的 SpringBoot 启动过程以及…

Milvus与Zilliz Cloud:向量数据库高可用性的双重飞跃

向量数据库高可用性的重要性及其在现代数据分析中的关键作用 在数据爆炸式增长的今天,企业对于高效、准确地处理和分析大规模数据集的需求日益迫切。尤其是在人工智能、机器学习、图像识别、自然语言处理等领域,向量数据库因其对高维数据的高效存储与检索能力,成为了不可或…

Elasticsearch未授权访问漏洞

步骤一:使用以下Fofa语法进行Elasticsearch产品搜索.. fofa语法"Elasticsearch" && port"9200" 步骤二:存在未授权访问则直接进入到信息页面...不需要输入用户密码登陆. http://localhost:9200/_plugin/head/web管理界面 http://localhost:9200/…

【JavaEE】线程池

目录 前言 什么是线程池 线程池的优点 ThreadPollExecutor中的构造方法 corePoolSize && maximumPoolSize keepAliveTime && unit workQueue threadFactory 如何在java中使用线程池 1.创建线程池对象 2.调用submit添加任务 3.调用shutdown关闭线程池…

【Python】requests的response.text 和 urllib.request 的 response.read()的区别

刚写代码的时候&#xff0c;我经常会把requests 和 urllib下的request 包搞混&#xff0c;这两个请求响应的方法看起来很相似&#xff0c;但是写获取的方法是不一样的。 前者requests 是用response.text 来获取源码&#xff0c;而 urllib.request是用 response.read() 来获取h…

数学建模--智能算法之免疫算法

目录 基本原理 应用实例 代码示例 总结 免疫算法在免疫系统研究中的应用和进展是什么&#xff1f; 如何量化评估免疫算法在不同优化问题中的性能和效率&#xff1f; 免疫算法与其他智能优化算法&#xff08;如遗传算法、粒子群优化&#xff09;相比有哪些独特优势和局限性…

【C++】C++11的新特性 — 线程库 ,原子操作 , 条件变量

勇敢就是接受发生在你身上的事&#xff0c;并把它尽力做到最好。 -- 约翰・欧文 -- C11的新特性 1 线程1.1 线程概念1.2 C中的线程1.3 线程并行1.4 锁 2 原子操作3 条件变量Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读&#xff01;&#xff01;&#xff01;下…

编译和汇编的区别

一、编译 编译是将高级语言&#xff08;如C、C、Java等&#xff09;编写的源代码转换成计算机可以直接执行的低级语言&#xff08;通常是机器语言或汇编语言&#xff09;的过程 编译 —— 将人类可读的源代码转换为计算机可执行的指令集 编译过程 通常包括词法分析、语法分…

正点原子imx6ull-mini-Linux驱动之Linux 网络驱动实验

网络驱动是 linux 里面驱动三巨头之一&#xff0c;linux 下的网络功能非常强大&#xff0c;嵌入式 linux 中也常 常用到网络功能。前面我们已经讲过了字符设备驱动和块设备驱动&#xff0c;本章我们就来学习一下 linux 里面的网络设备驱动。 1&#xff1a;嵌入式网络简介 1.1…

如何给源代码加密?这款加密软件教给你操作步骤

给源代码加密是保护软件知识产权和商业机密的重要手段。以这款加密软件安企神为例&#xff0c;给源代码加密的过程可以概述为以下几个方面。 一、安企神软件概述 安企神是一款功能强大的企业安全加密软件&#xff0c;它提供了全面的源代码防泄漏解决方案。该软件通过透明文件加…

扩散模型系列笔记(一)——DDPM

直观理解 扩散模型分为前向过程&#xff08;扩散过程&#xff0c;Data → \to →Noise&#xff09;和后向过程&#xff08;生成过程或逆扩散过程&#xff0c;Noise → \to →Data&#xff09;。在前向过程中&#xff0c;对于每一个观测样本&#xff0c;不断向样本中添加少量噪…

Leetcode每日刷题之字符串中的第一个唯一字符(C++)

在学习的过程中对代码的熟练运用至关重要&#xff0c;练习解决实际问题就可以很好的锻炼自己的编程能力&#xff0c;接下来让我们练习这道 387.字符串中的第一个唯一字符 思路解析 根据题意我们可以知道这个字符串只有小写字母&#xff0c;并且可能包含多个唯一字符&#xff0…

Java---字符串string练习

目录&#xff1a; 1.将数字转换成罗马数字 2.键盘输入任意字符串&#xff0c;打乱里面的内容 3.返回字符串中最后一个单词长度 4.调整A字符串 看是否可与B字符串匹配 一&#xff1a; //键盘录入一个字符串// 长度小于等于9 只能是数字// -将内容变成罗马数字// Ⅰ Ⅱ Ⅲ Ⅳ…

智慧水务项目(二)django(drf)+angular 18 创建通用model,并对orm常用字段进行说明

一、说明 上一篇文章建立一个最简单的项目&#xff0c;现在我们建立一个公共模型&#xff0c;抽取公共字段&#xff0c;以便于后续模块继承&#xff0c;过程之中会对orm常用字段进行说明&#xff0c;用到的介绍一下 二、创建一个db.py 目录如下图 1、代码 from importlib im…

基于QT实现的简易WPS(已开源)

一、开发工具及开源地址&#xff1a; 开发工具&#xff1a;QTCreator &#xff0c;QT 5 开源地址&#xff1a; GitHub - Whale-xh/WPS_official: Simple WPS based on QTSimple WPS based on QT. Contribute to Whale-xh/WPS_official development by creating an acc…

推荐 3个实用且完全免费的在线工具,每天都会用到,无需登录打开即用

100font 100font是一个专业的免费商用字体下载网站&#xff0c;专注于收集、整理和分享各种免费无版权的商用字体。用户可以在这个平台上找到并下载简体中文、繁体中文、英文、日文、韩文等多种语言类型的字体。 该网站的特点包括清晰的分类和直观的下载流程&#xff0c;用户可…

进阶SpringBoot之 Spring 官网或 IDEA 快速构建项目

SpringBoot 就是一个 JavaWeb 的开发框架&#xff0c;约定大于配置 程序 数据结构 算法 微服务架构是把每个功能元素独立出来&#xff0c;再动态组合&#xff0c;是对功能元素的复制 这样做可以节省调用资源&#xff0c;每个功能元素的服务都是一个可替代、可独立升级的软…

算法混合杂项

基础类型 可用template 投影 是有方向的 求俩直线交点 推公式 q我们不知道&#xff0c;已知p1 p2&#xff0c;正弦定理&#xff0c;α可以用叉积表示出来 β同理 所以我们能求出p1q 已知piq 回归到我们上一个问题&#xff0c;已知方向和长度&#xff0c;我们就能够求出Voq …

C语言 ——— 学习并使用字符分类函数

目录 学习isupper函数 学习isdigit函数 学习tolower函数 将输入的字符串中把大写字母转换为小写字母并输出 学习isupper函数 参数部分&#xff1a; 形参需要传递的是一个字母&#xff0c;字符在ASCII码表上是以整型存储的&#xff0c;所以实参部分用(int c)没有问题 返回…

【iOS】AutoreleasePool自动释放池的实现原理

目录 ARC与MRC项目中的main函数自动释放池autoreleasepool {}实现原理AutoreleasePoolPage总结 objc_autoreleasePoolPush的源码分析autoreleaseNewPageautoreleaseFullPageautoreleaseNoPage autoreleaseFast总结 autorelease方法源码分析objc_autoreleasePoolPop的源码分析po…