9.0 Android中的网络技术
Android中网络相关的技术,主要分别两种,一种为直接显示网页,另外一种为获取服务器中的数据进行设置。
权限声明
访问网络是需要声明权限
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.webviewtest"><uses-permission android:name="android.permission.INTERNET" />...</manifest>
WebView的使用
通过WebView的控件,直接显示网页,不需要考虑网页中的具体数据。
class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)webView.settings.javaScriptEnabled=truewebView.webViewClient = WebViewClient()webView.loadUrl("https://www.baidu.com")}}
调用了WebView的setWebViewClient()方法,并传入了一个WebViewClient的实例。这段代码的作用是,当需要从一个网页跳转到另一个网页时,我们希望目标网页仍然在当前WebView中显示,而不是打开系统浏览器。
HttpURLConnection的使用
get获取数据
class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)sendRequestBtn.setOnClickListener {sendRequestWithHttpURLConnection()}}private fun sendRequestWithHttpURLConnection() {// 开启线程发起网络请求thread {var connection: HttpURLConnection? = nulltry {val response = StringBuilder()val url = URL("https://www.baidu.com")connection = url.openConnection() as HttpURLConnectionconnection.connectTimeout = 8000connection.readTimeout = 8000val input = connection.inputStream// 下面对获取到的输入流进行读取val reader = BufferedReader(InputStreamReader(input))reader.use {reader.forEachLine {response.append(it)}}} catch (e: Exception) {e.printStackTrace()} finally {connection?.disconnect()}}}}
}
post发送数据
connection.requestMethod = "POST"
val output = DataOutputStream(connection.outputStream)
output.writeBytes("username=admin&password=123456")
okHttp的使用
项目主页地址:
https://github.com/square/okhttp
添加依赖:
dependencies {...implementation 'com.squareup.okhttp3:okhttp:4.1.0'
}
版本根据官网中的最新版本进行添加
okHttp的具体用法
获取Client的实例
val client = OkHttpClient()
创建get的request实例
创建request,需要知道是否需要设置token
val request = Request.Builder().url("https://www.baidu.com").build()
获取response
同步获取
val response = client.newCall(request).execute()
val responseData = response.body?.string()
异步获取:
client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(@NotNull Call call, @NotNull IOException e) {//响应失败}@Overridepublic void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {//响应成功val responseData = response.body?.string()}});
发起Post的请求
val requestBody = FormBody.Builder().add("username", "admin").add("password", "123456").build()val request = Request.Builder().url("https://www.baidu.com").post(requestBody).build()
从Android 9.0系统开始,应用程序默认只允许使用HTTPS类型的网络请求,HTTP类型的网络请求因为有安全隐患默认不再被支持,如果使用的是HTTP,需要设置文件,res -> xml ->network_config.xml文件。
<?xml version="1.0" encoding="utf-8"?>
<network-security-config><base-config cleartextTrafficPermitted="true"><trust-anchors><certificates src="system" /></trust-anchors></base-config>
</network-security-config>
这段配置文件是允许我们以明文的方式在网络上传输数据,而HTTP使用的就是明文传输方式。
需要修改manifest文件中的内容,如下所示:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.networktest">...<applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"android:networkSecurityConfig="@xml/network_config">...</application>
</manifest>
解析XML数据的两种方法:
①pull方法
方法parseXMLWithPull中的,即为使用Pull方法解析XML格式的数据
class MainActivity : AppCompatActivity() {...private fun sendRequestWithOkHttp() {thread {try {val client = OkHttpClient()val request = Request.Builder()// 指定访问的服务器地址是计算机本机.url("http://10.0.2.2/get_data.xml").build()val response = client.newCall(request).execute()val responseData = response.body?.string()if (responseData != null) {parseXMLWithPull(responseData)}} catch (e: Exception) {e.printStackTrace()}}}...private fun parseXMLWithPull(xmlData: String) {try {val factory = XmlPullParserFactory.newInstance()val xmlPullParser = factory.newPullParser()xmlPullParser.setInput(StringReader(xmlData))var eventType = xmlPullParser.eventTypevar id = ""var name = ""var version = ""while (eventType != XmlPullParser.END_DOCUMENT) {val nodeName = xmlPullParser.namewhen (eventType) {// 开始解析某个节点XmlPullParser.START_TAG -> {when (nodeName) {"id" -> id = xmlPullParser.nextText()"name" -> name = xmlPullParser.nextText()"version" -> version = xmlPullParser.nextText()}}// 完成解析某个节点XmlPullParser.END_TAG -> {if ("app" == nodeName) {Log.d("MainActivity", "id is $id")Log.d("MainActivity", "name is $name")Log.d("MainActivity", "version is $version")}}}eventType = xmlPullParser.next()}} catch (e: Exception) {e.printStackTrace()}}
}
②SAX方法
class MainActivity : AppCompatActivity() {...private fun sendRequestWithOkHttp() {thread {try {val client = OkHttpClient()val request = Request.Builder()// 指定访问的服务器地址是计算机本机.url("http://10.0.2.2/get_data.xml").build()val response = client.newCall(request).execute()val responseData = response.body?.string()if (responseData != null) {parseXMLWithSAX(responseData)}} catch (e: Exception) {e.printStackTrace()}}}...private fun parseXMLWithSAX(xmlData: String) {try {val factory = SAXParserFactory.newInstance()val xmlReader = factory.newSAXParser().XMLReaderval handler = ContentHandler()// 将ContentHandler的实例设置到XMLReader中xmlReader.contentHandler = handler// 开始执行解析xmlReader.parse(InputSource(StringReader(xmlData)))} catch (e: Exception) {e.printStackTrace()}}
}
ContentHandler的定义:
class ContentHandler : DefaultHandler() {private var nodeName = ""private lateinit var id: StringBuilderprivate lateinit var name: StringBuilderprivate lateinit var version: StringBuilderoverride fun startDocument() {id = StringBuilder()name = StringBuilder()version = StringBuilder()}override fun startElement(uri: String, localName: String, qName: String, attributes:Attributes) {// 记录当前节点名nodeName = localNameLog.d("ContentHandler", "uri is $uri")Log.d("ContentHandler", "localName is $localName")Log.d("ContentHandler", "qName is $qName")Log.d("ContentHandler", "attributes is $attributes")}override fun characters(ch: CharArray, start: Int, length: Int) {// 根据当前节点名判断将内容添加到哪一个StringBuilder对象中when (nodeName) {"id" -> id.append(ch, start, length)"name" -> name.append(ch, start, length)"version" -> version.append(ch, start, length)}}override fun endElement(uri: String, localName: String, qName: String) {if ("app" == localName) {Log.d("ContentHandler", "id is ${id.toString().trim()}")Log.d("ContentHandler", "name is ${name.toString().trim()}")Log.d("ContentHandler", "version is ${version.toString().trim()}")// 最后要将StringBuilder清空id.setLength(0)name.setLength(0)version.setLength(0)}}override fun endDocument() {}}
id、name和version中都可能是包括回车或换行符的,需要调用trim。
解析JSON数据
官方提供的JSONObject,使用Google的开源库GSON。或者使用一些第三方的开源库如Jackson、FastJSON等。
①官方的JSONObject
......private fun parseJSONWithJSONObject(jsonData: String) {try {val jsonArray = JSONArray(jsonData)for (i in 0 until jsonArray.length()) {val jsonObject = jsonArray.getJSONObject(i)val id = jsonObject.getString("id")val name = jsonObject.getString("name")val version = jsonObject.getString("version")Log.d("MainActivity", "id is $id")Log.d("MainActivity", "name is $name")Log.d("MainActivity", "version is $version")}} catch (e: Exception) {e.printStackTrace()}}
}
②使用GSON解析
添加依赖
dependencies {...implementation 'com.google.code.gson:gson:2.8.5'
}
解析一段字符串
{“name”:“Tom”,“age”:20}
设置Person的类,直接进行转换
val gson = Gson()
val person = gson.fromJson(jsonData, Person::class.java)
解析字符串数组
需要借助TypeToken将期望解析成的数据类型传入fromJson()方法中
val typeOf = object : TypeToken<List<Person>>() {}.type
val people = gson.fromJson<List<Person>>(jsonData, typeOf)
jsonData为需要解析的字符串数组
网络请求回调方法:
interface HttpCallbackListener {fun onFinish(response: String)fun onError(e: Exception)
}
object HttpUtil {fun sendHttpRequest(address: String, listener: HttpCallbackListener) {thread {var connection: HttpURLConnection? = nulltry {val response = StringBuilder()val url = URL(address)connection = url.openConnection() as HttpURLConnectionconnection.connectTimeout = 8000connection.readTimeout = 8000val input = connection.inputStreamval reader = BufferedReader(InputStreamReader(input))reader.use {reader.forEachLine {response.append(it)}}// 回调onFinish()方法listener.onFinish(response.toString())} catch (e: Exception) {e.printStackTrace()// 回调onError()方法listener.onError(e)} finally {connection?.disconnect()}}}}
使用json
object HttpUtil {...fun sendOkHttpRequest(address: String, callback: okhttp3.Callback) {val client = OkHttpClient()val request = Request.Builder().url(address).build()client.newCall(request).enqueue(callback)}
}
使用
HttpUtil.sendOkHttpRequest(address, object : Callback {override fun onResponse(call: Call, response: Response) {// 得到服务器返回的具体内容val responseData = response.body?.string()}override fun onFailure(call: Call, e: IOException) {// 在这里对异常情况进行处理}
})
相关文章:
9.0 Android中的网络技术
Android中网络相关的技术,主要分别两种,一种为直接显示网页,另外一种为获取服务器中的数据进行设置。 权限声明 访问网络是需要声明权限 <manifest xmlns:android"http://schemas.android.com/apk/res/android"package"…...
linux查看端口是否被占用 / 包含某个字符的文件/当前正在运行的进程/根据端口号查找进程
查看端口是否被占用 netstat -tuln | grep 80查看包含某个字符的文件 grep -rl "aaa" .r :递归搜索子目录。l :只显示包含匹配字符串的文件名。 ack "your_string"查看当前正在运行的进程 ps aux或者使用 top 命令用于实时显示当…...
解锁 JavaScript ES6:函数与对象的高级扩展功能
个人主页:学习前端的小z 个人专栏:JavaScript 精粹 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结,欢迎大家在评论区交流讨论! ES5、ES6介绍 文章目录 💯ES6函数扩展🍓1 默认参数ἵ…...
算法金 | 10 大必知的自动化机器学习库(Python)
本文来源公众号“算法金”,仅用于学术分享,侵权删,干货满满。 原文链接:10 大必知的自动化机器学习库(Python) 一、入门级自动化机器学习库 1.1 Auto-Sklearn 简介: Auto-Sklearn 是一个自动…...
微信小游戏开发难度大吗?开发流程有哪些?
微信小游戏的开发难度因项目的复杂度和规模而定,一般来说,休闲益智类的小游戏的开发周期相对较短,大约在10个工作日到1个月。如果涉及到复杂的算法、高级的交互或特殊的效果,开发时间可能会相应延长。 微信小游戏的开发流程包括需…...
Qt程序打包成单个exe文件
文章目录 0. 准备工作1. 使用 windeployqt 提取必要的动态链接库和资源文件1.1 操作步骤1.2 补充 2. 使用 Enigma Virtual Box将文件夹打包成单个exe2.1 操作步骤 0. 准备工作 Qt程序打包用到的工具有: windeployqt :安装Qt时自带Enigma Virtual Box 下…...
【机器学习】GANs网络在图像和视频技术中的应用前景
📝个人主页:哈__ 期待您的关注 目录 1. 🔥引言 背景介绍 研究意义 2. 🎈GANs的基本概念和工作原理 生成对抗网络简介 工作原理 3. 🤖GANs在图像生成中的应用 图像超分辨率 工作原理 图像去噪 工作原理 图…...
MFC 使用sapi文字转换为语音
文章目录 添加头文件声明变量 添加头文件 声明变量 pSpVoice NULL; //默认构造函数中初始化为空 bool CChKBarSCCodeApp::InitSpVoice() {HRESULT hr ::CoInitialize(NULL); // COM初始化if (!SUCCEEDED(hr)){AfxMessageBox(_T("声音环境初始化失败!…...
(Git)多人协作1
文章目录 前言总结 前言 目标:master分支下file.txt文件新增“aaa”,“bbb” 实现:开发者1新增“aaa”,开发者2新增“bbb” 条件:在同一个分支下协作完成 实际开发过程中,每个用户都与属于自己的码云账户,如果想要进…...
MySQL-分组函数
041-分组函数 重点:所有的分组函数都是自动忽略NULL的 分组函数的执行原则:先分组,然后对每一组数据执行分组函数。如果没有分组语句group by的话,整张表的数据自成一组。 分组函数包括五个: max:最大值mi…...
【C语言】联合(共用体)
目录 一、什么是联合体 二、联合类型的声明 三、联合变量的创建 四、联合的特点 五、联合体大小的计算 六、联合的应用(判断大小端) 七、联合体的优缺点 7.1 优点 7.2 缺点 一、什么是联合体 联合也是一种特殊的自定义类型。由多个不同类型的数…...
【博客715】如何从victorimametrics集群中下线vmstorage节点
How to Decommission a vmstorage Node from a VictoriaMetrics Cluster 我们需要从VictoriaMetrics 集群中优雅地移除一个 vmstorage 节点。每个 vmstorage 节点都包含自己的数据部分,从集群中移除 vmstorage 节点会导致图表出现空白(因为复制超出了范…...
Redis缓存技术详解与实战
Redis缓存技术详解与实战 Redis作为一个开源的内存数据结构存储系统,它可以用作数据库、缓存和消息代理。在现代高并发、大数据量处理的系统中,Redis作为缓存层的应用越来越广泛。本文将详细讲解Redis在查询、添加缓存、更新缓存、缓存预热、缓存穿透、…...
业务架构的位置及关系
背景 我们已经了解了业务架构的核心元素组成,以及各个扩展元素,同时对各个元素的关系协同也有了一些了解,那么接下来,我们进一步在宏观层面来看业务架构与其他架构的关系。 企业架构 企业架构有多种理解,也有多种叫…...
CMS与AI的融合:构建万能表单小程序系统
引言: 随着人工智能技术的飞速发展,MyCMS作为一款功能强大的内容管理系统,通过集成AI技术,进一步拓展了其应用范围和智能化水平。本文将探讨如何利用MyCMS结合AI技术,构建一个能够将用户提交的万能表单数据转化为智能提…...
机器学习常见知识点 2:决策树
文章目录 决策树算法1、决策树树状图2、选择最优决策条件3、决策树算法过程→白话决策树原理决策树构建的基本步骤常见的决策树算法决策树的优缺点 【五分钟机器学习】可视化的决策过程:决策树 Decision Tree 关键词记忆: 纯度、选择最优特征分裂、熵、基…...
海洋CMS admin_notify.php 远程代码执行漏洞复现(CVE-2024-30565)
0x01 产品简介 海洋CMS是一套专为不同需求的站长而设计的内容管理系统,灵活、方便、人性化设计、简单易用是最大的特色,可快速建立一个海量内容的专业网站。海洋CMS基于PHP+MySql技术开发,完全开源免费 、无任何加密代码。 0x02 漏洞概述 海洋CMS admin_notify.php 接口处…...
Spring、Spring MVC、MyBatis和Spring Boot对比
在对比Spring、Spring MVC、MyBatis和Spring Boot时,我们可以从以下几个方面进行详细的分析: Spring框架: 作用:Spring是一个轻量级的IoC(控制反转)和AOP(面向切面编程)容器&#…...
【Linux高级IO】select、poll、epoll
【Linux高级IO】select、poll、epoll toc 作者:爱写代码的刚子 时间:2024.6.5 前言:本篇博客将会介绍面试重点考察的select、poll、epoll IO: input && Output read && write 应用层read&&write的时候,…...
Etcd Raft架构设计和源码剖析2:数据流
Etcd Raft架构设计和源码剖析2:数据流 | Go语言充电站 前言 之前看到一幅描述etcd raft的流程图,感觉非常直观,但和自己看源码的又有些不同,所以自己模仿着画了一下,再介绍一下。 下图从左到右依次分为4个部分&…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
