HarmonyOS 页面路由(Router)
1. HarmonyOS页面路由(Router)
页面路由指在应用程序中实现不同页面之间的跳转和数据传递。HarmonyOS提供了Router模块,通过不同的url地址,可以方便地进行页面路由,轻松地访问不同的页面。本文将从页面跳转、页面返回和页面返回前增加一个询问框几个方面介绍Router模块提供的功能。
1.1. 页面跳转
页面跳转是开发过程中的一个重要组成部分。在使用应用程序时,通常需要在不同的页面之间跳转,有时还需要将数据从一个页面传递到另一个页面。
1.1.1. 跳转模式
Router模块提供了两种跳转模式,分别是router.pushUrl()和router.replaceUrl()。这两种模式决定了目标页是否会替换当前页。
(1)router.pushUrl():目标页不会替换当前页,而是压入页面栈。这样可以保留当前页的状态,并且可以通过返回键或者调用router.back()方法返回到当前页。
(2)router.replaceUrl():目标页会替换当前页,并销毁当前页。这样可以释放当前页的资源,并且无法返回到当前页。
说明:页面栈的最大容量为32个页面。如果超过这个限制,可以调用router.clear()方法清空历史页面栈,释放内存空间。
1.1.2.实例模式
Router模块提供了两种实例模式,分别是Standard和Single。这两种模式决定了目标url是否会对应多个实例。
(1)Standard:标准实例模式,也是默认情况下的实例模式。每次调用该方法都会新建一个目标页,并压入栈顶。
(2)Single:单实例模式。即如果目标页的url在页面栈中已经存在同url页面,则离栈顶最近的同url页面会被移动到栈顶,并重新加载;如果目标页的url在页面栈中不存在同url页面,则按照标准模式跳转。
1.2. 场景
1.2.1.场景一
有一个主页(Home)和一个详情页(Detail),希望从主页点击一个商品,跳转到详情页。同时,需要保留主页在页面栈中,以便返回时恢复状态。这种场景下,可以使用pushUrl()方法,并且使用Standard实例模式(或者省略)。标准实例模式下,router.RouterMode.Standard参数可以省略。
private standardClick() {router.pushUrl({url: 'pages/myTool/RouterTwoPage' // 目标url}, router.RouterMode.Standard, (err) => {if (err) {console.error(`Invoke pushUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke pushUrl succeeded.');});}
1.2.2.场景二
有一个登录页(Login)和一个个人中心页(Profile),希望从登录页成功登录后,跳转到个人中心页。同时,销毁登录页,在返回时直接退出应用。这种场景下,可以使用replaceUrl()方法,并且使用Standard实例模式(或者省略)。
private standardReplaceClick() {router.replaceUrl({url: 'pages/myTool/RouterTwoPage'}, router.RouterMode.Standard, (err) => {if (err) {console.error(`Invoke replaceUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke replaceUrl succeeded.');})}
1.2.3.场景三
有一个设置页(Setting)和一个主题切换页(Theme),希望从设置页点击主题选项,跳转到主题切换页。同时,需要保证每次只有一个主题切换页存在于页面栈中,在返回时直接回到设置页。这种场景下,可以使用pushUrl()方法,并且使用Single实例模式。
private singleClick() {router.pushUrl({url: 'pages/myTool/RouterTwoPage'}, router.RouterMode.Single, (err) => {if (err) {console.error(`Invoke pushUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke pushUrl succeeded.');});}
1.2.4.场景四
有一个搜索结果列表页(SearchResult)和一个搜索结果详情页(SearchDetail),希望从搜索结果列表页点击某一项结果,跳转到搜索结果详情页。同时,如果该结果已经被查看过,则不需要再新建一个详情页,而是直接跳转到已经存在的详情页。这种场景下,可以使用replaceUrl()方法,并且使用Single实例模式。
private single2Click() {router.replaceUrl({url: 'pages/myTool/RouterTwoPage' // 目标url}, router.RouterMode.Single, (err) => {if (err) {console.error(`Invoke replaceUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke replaceUrl succeeded.');})
}
1.2.5.场景五
如果需要在跳转时传递一些数据给目标页,则可以在调用Router模块的方法时,添加一个params属性,并指定一个对象作为参数。例如:
(1)RouterBean
export class RouterItemBean {id?: stringtitle?: string
}
export class RouterBean {mainId?: string;routerItemBean?: RouterItemBean;
}
(2)带参跳转
private paramsClick() {let paramsInfo: RouterBean = {mainId: "123",routerItemBean: {id: "456",title: "789",}};router.pushUrl({url: 'pages/myTool/RouterTwoPage', // 目标urlparams: paramsInfo // 添加params属性,传递自定义参数}, (err) => {if (err) {console.error(`Invoke pushUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke pushUrl succeeded.');})}
(3)在目标页中,可以通过调用Router模块的getParams()方法来获取传递过来的参数。例如:
aboutToAppear() {try {// 获取传递过来的参数对象this.routerBean = (router.getParams() as RouterBean);let mainId = this.routerBean.mainId;let routerItem = this.routerBean.routerItem;let id = routerItem?.id;let title = routerItem?.title;this.msg="获取传过来的数据:"+mainId+id+title} catch (e) {}}
1.3.页面返回
当用户在一个页面完成操作后,通常需要返回到上一个页面或者指定页面,这就需要用到页面返回功能。在返回的过程中,可能需要将数据传递给目标页,这就需要用到数据传递功能。
1.3.1.方式一: 返回到上一个页面
这种方式会返回到上一个页面,即上一个页面在页面栈中的位置。但是,上一个页面必须存在于页面栈中才能够返回,否则该方法将无效。
private routerClick() {//router.back(2)router.back()}
1.3.2.方式二:返回到指定页面
这种方式可以返回到指定页面,需要指定目标页的路径。目标页必须存在于页面栈中才能够返回。
private back2Click() {router.back({url: 'pages/myTool/RouterOnePage'});}
1.3.3.方式三:返回到指定页面,并传递自定义参数信息
这种方式不仅可以返回到指定页面,还可以在返回的同时传递自定义参数信息。这些参数信息可以在目标页中通过调用router.getParams()方法进行获取和解析。
private back3Click() {let paramsInfo: RouterBean = {mainId: "111",routerItem: {id: "222",title: "333",},};router.back({url: 'pages/myTool/RouterOnePage',params: paramsInfo});}
在目标页中,在需要获取参数的位置调用router.getParams()方法即可,例如在onPageShow()生命周期回调中:
onPageShow() {try {// 获取传递过来的参数对象this.routerBean = (router.getParams() as RouterBean);let mainId = this.routerBean.mainId;let routerItem = this.routerBean.routerItem;let id = routerItem?.id;let title = routerItem?.title;this.msg="获取传过来的数据:"+mainId+id+title} catch (e) {}}
当使用router.back()方法返回到指定页面时,原栈顶页面(包括)到指定页面(不包括)之间的所有页面栈都将从栈中弹出并销毁。
另外,如果使用router.back()方法返回到原来的页面,原页面不会被重复创建,因此使用@State声明的变量不会重复声明,也不会触发页面的aboutToAppear()生命周期回调。如果需要在原页面中使用返回页面传递的自定义参数,可以在需要的位置进行参数解析。例如,在onPageShow()生命周期回调中进行参数解析。
1.4.完整代码
1.4.1.RouterBean.ets
export class RouterItem {id?: stringtitle?: string
}export class RouterArr {array?:string[]
}export class RouterBean {mainId?: string;routerItem?: RouterItem;routerArr?: RouterArr;
}
1.4.2.RouterOnePage.ets
import { TitleBar } from '../../components/common/TitleBar'
import { router } from '@kit.ArkUI'
import { RouterParams } from '../../helper/RouterHelper'
import { BusinessError } from '@kit.BasicServicesKit'
import { Logger } from '../../utils/Logger'
import { RouterBean } from '../../bean/RouterBean'@Extend(Button)
function buttonItem() {.stateEffect(true).type(ButtonType.Normal).borderRadius(8).fontSize(17).backgroundColor($r('app.color.primary_green')).padding({top: 8,bottom: 8,left: 70,right: 70}).margin({top: 15,bottom: 15})
}@Entry
@Component
struct RouterOnePage {@State pageTitle: string = "路由跳转"private routerBean?: RouterBeanprivate msg: string = '3f3d4 'aboutToAppear() {try {this.pageTitle = (router.getParams() as RouterParams).title} catch (e) {}}onPageShow() {try {// 获取传递过来的参数对象this.routerBean = (router.getParams() as RouterBean);let mainId = this.routerBean.mainId;let routerItem = this.routerBean.routerItem;let id = routerItem?.id;let title = routerItem?.title;this.msg="获取传过来的数据:"+mainId+id+title} catch (e) {}}/*** router.pushUrl()*/async routerClick() {//router.pushUrl()//目标页面不会替换当前页,而是压入页面栈。// 这样可以保留当前页的状态,并且可以通过返回键// 或者调用router.back()方法返回到当前页。let options: router.RouterOptions = {url: 'pages/myTool/RouterTwoPage',params: new RouterParams("路由跳转", [12, 45, 78])}try {await router.pushUrl(options)} catch (err) {console.info(` fail callback,code: ${(err as BusinessError).code},msg: ${(err as BusinessError).message}`)}}/*** router.replaceUrl()*/async replaceRouterClick() {router.replaceUrl({ url: 'pages/myTool/RouterTwoPage' }).catch((err: Error) => {Logger.error(JSON.stringify(err));})}/***有一个主页(Home)和一个详情页(Detail),* 希望从主页点击一个商品,跳转到详情页。* 同时,需要保留主页在页面栈中,以便返回时恢复状态。* 这种场景下,可以使用pushUrl()方法,* 并且使用Standard实例模式(或者省略)。*/private standardClick() {router.pushUrl({url: 'pages/myTool/RouterTwoPage' // 目标url}, router.RouterMode.Standard, (err) => {if (err) {console.error(`Invoke pushUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke pushUrl succeeded.');});}/*** 有一个登录页(Login)和一个个人中心页(Profile),* 希望从登录页成功登录后,跳转到个人中心页。* 同时,销毁登录页,在返回时直接退出应用。* 这种场景下,可以使用replaceUrl()方法,* 并且使用Standard实例模式(或者省略)。*/private standardReplaceClick() {router.replaceUrl({url: 'pages/myTool/RouterTwoPage'}, router.RouterMode.Standard, (err) => {if (err) {console.error(`Invoke replaceUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke replaceUrl succeeded.');})}/*** 有一个设置页(Setting)和一个主题切换页(Theme),* 希望从设置页点击主题选项,跳转到主题切换页。* 同时,需要保证每次只有一个主题切换页存在于页面栈中,* 在返回时直接回到设置页。这种场景下,可以使用pushUrl()方法,* 并且使用Single实例模式。*/private singleClick() {router.pushUrl({url: 'pages/myTool/RouterTwoPage'}, router.RouterMode.Single, (err) => {if (err) {console.error(`Invoke pushUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke pushUrl succeeded.');});}/***有一个搜索结果列表页(SearchResult)和一个搜索结果详情页(SearchDetail),* 希望从搜索结果列表页点击某一项结果,跳转到搜索结果详情页。* 同时,如果该结果已经被查看过,则不需要再新建一个详情页,* 而是直接跳转到已经存在的详情页。这种场景下,可以使用replaceUrl()方法,* 并且使用Single实例模式。*/private single2Click() {router.replaceUrl({url: 'pages/myTool/RouterTwoPage' // 目标url}, router.RouterMode.Single, (err) => {if (err) {console.error(`Invoke replaceUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke replaceUrl succeeded.');})}/***如果需要在跳转时传递一些数据给目标页,则可以在调用Router模块的方法时,* 添加一个params属性,并指定一个对象作为参数。例如:*/private paramsClick() {let paramsInfo: RouterBean = {mainId: "123",routerItem: {id: "456",title: "789",},};router.pushUrl({url: 'pages/myTool/RouterTwoPage', // 目标urlparams: paramsInfo // 添加params属性,传递自定义参数}, (err) => {if (err) {console.error(`Invoke pushUrl failed, code is ${err.code},message is ${err.message}`);return;}console.info('Invoke pushUrl succeeded.');})}build() {Column() {TitleBar({ pageTitle: $pageTitle })Button('路由跳转').buttonItem().onClick(this.routerClick)Button('销毁跳转').buttonItem().onClick(this.replaceRouterClick)Button('standard').buttonItem().onClick(this.standardClick)Button('standardReplace').buttonItem().onClick(this.standardReplaceClick)Button('single').buttonItem().onClick(this.singleClick)Button('single2').buttonItem().onClick(this.single2Click)Button('带参路由').buttonItem().onClick(this.paramsClick)Text(this.msg).fontSize(18).fontColor($r('app.color.primary_font_title')).margin({ top: 20 })}.height('100%')}
}
1.4.3.RouterTwoPage.ets
import { TitleBar } from '../../components/common/TitleBar'
import { router } from '@kit.ArkUI'
import { RouterParams } from '../../helper/RouterHelper'
import { BusinessError } from '@kit.BasicServicesKit'
import { Logger } from '../../utils/Logger'
import { RouterBean } from '../../bean/RouterBean'@Extend(Button)
function buttonItem() {.stateEffect(true).type(ButtonType.Normal).borderRadius(8).fontSize(17).backgroundColor($r('app.color.primary_green')).padding({top: 8,bottom: 8,left: 70,right: 70}).margin({top: 15,bottom: 15})
}@Entry
@Component
struct RouterTwoPage {@State pageTitle: string = "路由跳转二"private routerBean?: RouterBeanprivate msg: string = '3f3d4 'aboutToAppear() {try {// 获取传递过来的参数对象this.routerBean = (router.getParams() as RouterBean);let mainId = this.routerBean.mainId;let routerItem = this.routerBean.routerItem;let id = routerItem?.id;let title = routerItem?.title;this.msg="获取传过来的数据:"+mainId+id+title} catch (e) {}}/*** 返回到上一个页面*/private backClick() {//router.back(2)router.back()}/*** 返回指定页面*/private back2Click() {router.back({url: 'pages/myTool/RouterOnePage'});}/*** 返回到指定页面,并传递自定义参数信息*/private back3Click() {let paramsInfo: RouterBean = {mainId: "111",routerItem: {id: "222",title: "333",},};router.back({url: 'pages/myTool/RouterOnePage',params: paramsInfo});}build() {Column() {TitleBar({ pageTitle: $pageTitle })Button('返回到上一个页面').buttonItem().onClick(this.backClick)Button('返回指定页面').buttonItem().onClick(this.back2Click)Button('传参返回').buttonItem().onClick(this.back3Click)Text(this.msg).fontSize(18).fontColor($r('app.color.primary_font_title')).margin({ top: 20 })}.height('100%')}
}
相关文章:

HarmonyOS 页面路由(Router)
1. HarmonyOS页面路由(Router) 页面路由指在应用程序中实现不同页面之间的跳转和数据传递。HarmonyOS提供了Router模块,通过不同的url地址,可以方便地进行页面路由,轻松地访问不同的页面。本文将从页面跳转、页面返回和页面返回前增加一个询问…...
Python 正则表达式语法
Python 中的正则表达式是通过 re 模块提供的,它支持大多数正则表达式的语法。以下是一些基本的正则表达式语法元素: 字符匹配: . 匹配任意单个字符,除了换行符。\d 匹配任意数字,等同于 [0-9]。\D 匹配任意非数字字符,…...

计算机专业毕设-校园二手交易平台
1 项目介绍 基于SpringBoot的校园二手交易平台:前端Freemarker,后端 SpringBoot、Jpa,系统用户分为两类,管理员、学生,具体功能如下: 管理员: 基本功能:登录、修改个人信息、修改…...

微信小程序添加服务类目|《非经营性互联网信息服务备案核准》怎么获取
根据客服反馈,《非经营性互联网信息服务备案核准》在工业和信息化部政务服务平台网站查询,查询结果的截图就是《非经营性互联网信息服务备案核准》。 工业和信息化部政务服务平台 《非经营性互联网信息服务备案核准》: 与客服聊天的截图&a…...

Internet Download Manager ( 极速下载器 ) 序列号注册码 IDM下载器注册机中文激活破解版
IDM下载器(Internet Download Manager)是一款专业的下载管理软件,它通过多线程技术和智能文件分段技术,有效提升下载速度,并支持断点续传,还具有计划下载功能,用户可以设置特定的下载时间,非常适合需要在特…...

FPGA - 滤波器 - IIR滤波器设计
一,IIR滤波器 在FPGA - 滤波器 - FIR滤波器设计中可知,数字滤波器是一个时域离散系统。任何一个时域离散系统都可以用一个N阶差分方程来表示,即: 式中,x(n)和y(n)分别是系统的输入序列和输出序列;aj和bi均为…...

练习时长 1 年 2 个月的 Java 菜鸡练习生最近面经,期望25K
面经哥只做互联网社招面试经历分享,关注我,每日推送精选面经,面试前,先找面经哥 自我介绍:本人是练习时长 1 年 2 个月的 Java 后端菜鸡练习生。下面是我最近面试的面经: 百度 一面 约1h时间:2…...

计算机跨考现状,两极分化现象很严重
其实我觉得跨考计算机对于一些本科学过高数的同学来说有天然的优势 只要高数能学会,那计算机那几本专业课,也能很轻松的拿下,而对于本科是文科类的专业,如果想跨考计算机,难度就不是一般的大了。 现在跨考计算机呈现…...

leetcode73 矩阵置零
题目 给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]] 解析 这道题题目上要求用原地算法…...
了解 XML HttpRequest 及其在 Web 开发中的应用
XML HttpRequest(XHR) 技术是构建动态、响应式网站的关键。这项技术使得网页能在不重新加载整个页面的情况下与服务器进行数据交互,极大地优化了用户的交互体验。 定义 XML HttpRequest XML HttpRequest 是一种浏览器与服务器进行数据交换的…...
CPU与GPU的原理不同
CPU(中央处理器)和GPU(图形处理器)在设计原理上有很大的不同。CPU是通用的计算核心,擅长处理复杂的控制流和数据结构,而GPU则是为了并行处理大量相似的计算任务而设计的。二者是计算机系统中两种不同类型的…...
嵌入式相关基础
一.常见的芯片类型 1.微控制器(MCU) (1)STM32 主频(MHz)内核Flash(Kbytes)Ram(Kbytes)封装ADC channels DAC channels SPISTM32F407ZG168ARM Cortex-M4f1024192LQFP1442423STM32F407ZE168ARM Cortex-M4f512192LQFP1442423STM32F407VE168ARM Cortex-M4f512192LQFP1001623STM32…...

无线麦克风推荐哪些品牌?一文读懂家用无线麦克风哪个牌子好!
在这个充满创意与表达的时代,无线领夹麦克风以其独特的魅力,成为了声音创作者们的得力助手。它小巧便携,功能强大,无论是日常拍摄、直播互动还是专业演出,都能轻松应对,让你的声音随时随地清晰传递。那么…...
构建SOA架构时应该注意的问题
1.原有系统架构中的集成需求 面向服务的体系结构本质上来说是一种具有特殊性质的体系结构,它由具有互操作性和位置透明的组件集成构建并互连而成。基于SOA的企业系统架构通常都是在现有系统架构投资的基础上发展起来的,我们并不需要彻底重新开发全部的子…...

动手学深度学习(Pytorch版)代码实践 -深度学习基础-13Kaggle竞赛:2020加州房价预测
13Kaggle竞赛:2020加州房价预测 # 导入所需的库 import numpy as np import pandas as pd import torch import hashlib import os import tarfile import zipfile import requests from torch import nn from d2l import torch as d2l# 读取训练和测试数据 train_…...
编程输出中间变量:深度解析与实战应用
编程输出中间变量:深度解析与实战应用 在编程过程中,中间变量是一个至关重要的概念。它们不仅有助于我们更好地理解和组织代码,还能提高程序的效率和可读性。那么,编程输出中间变量究竟是什么呢?本文将从四个方面、五…...

冒泡排序、选择排序
冒泡排序 按照冒泡排序的思想,我们要把相邻的元素两两比较,当一个元素大于右侧相元素时,交换它们的位置;当一个元素小于或等于右侧相邻元素时,位置不变 大的往右丢(往下沉),小的往…...

嵌入式实训day6
1、 from machine import Pin from neopixel import NeoPixel import timeif __name__"__main__"#创建RBG灯带控制对象,包含5个像素(5个RGB LED)rgb_led NeoPixel(Pin(4,Pin.OUT),5)#定义RGB颜色RED(255,0,0)GREEN(0,2…...
产品经理是青春饭吗?终于有了答案!
不少考生疑惑产品经理是青春饭吗?产品经理能干到多少岁?弄清楚这些问题,我们才会有长久的规划。产品经理是青春饭吗?产品经理能干到多少岁?一起来看看 一、产品经理是青春饭吗? 产品经理是否吃青春饭需要…...

FPGA - 数 - 加减乘除
一,数的表示 首先,将二进制做如下解释: 2的0次方1 2的1次方2 2的2次方4 2的3次方8 ..... 以此类推,那么任何整数,或者说任意一个自然数均可以采用这种方式来表示。 例如,序列10101001,根据上述…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...