【小程序 - 大智慧】深入微信小程序的核心原理
目录
- 课程目标
- 背景
- 双线程架构
- WebView 结构
- 快速渲染 PageFrame
- 编译原理
- Exparser
- 通讯系统
- 生命周期
- 基础库解包
- 跨端框架
- 预编译
- 半编译半运行
- 运行时框架
- 主流技术
- Taro
- uni-app
- 汇总
- 下周安排
课程目标
本次课程主要通过后台管理小程序回顾一下小程序的高阶语法,然后讲解整体小程序流程原理:
- 前端相关的编码规范、设计规范
- 页面切换、生命周期、数据通信等基础知识
- 双线程架构、webview 渲染、PageFrame 模板、通讯系统、生命周期、跨端框架等
- 掘金小册推荐 https://juejin.cn/book/6982013809212784676
背景
https://zh.wikipedia.org/zh-cn/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F
微信小程序于 2017 年上线,当时企业普遍把 H5 作为公众号的引流入口,公众号正火,但是当时由于 H5 不安全、性能不好、占用存储空间大的问题,微信需要设计一个全新的系统进行迭代。
双线程架构
面试官:说说什么是进程?什么是线程?区别? | web前端面试 - 面试官系列
进程:操作系统进行进行资源分配和调度的基本单位
线程:操作系统能够进行运算调度的最小单位,其是进程中的一个执行任务(控制单元),负责当前进程中程序的执行
微信小程序的设计和前端浏览器是不一致的,它隔离了 JS 操作层 和 界面渲染层,前端是互通的,可以通过 window document 任意的调用 dom 元素和执行脚本,但是小程序作为微信的工具,势必不允许像 web 端这样自由的操作空间,所以:
- App Service(逻辑层):单纯执行 JavaScript 的沙箱环境,无法操作 Dom 和访问浏览器 Api ,只能借助 Native 异步查询 DOM 元素并操作,小程序的 WXML 和 WXSS 也会被编译为 JS 脚本进行注入操作。由于小程序内部只有一个 App 实例,通过这个 App 主线程 进行调度
- Web View(渲染层):单纯页面的展示,模拟 app 多页面模式,具有多个 webview ,可以暂时抽象成 浏览器的 tab 页面(并非 VUE 的单页面结构,像 App 多页面结构)
- Native(微信客户端):利用微信缓存机制,提前注入 微信 SDK、接口请求、组件渲染(wx.request、wx.showToast 都是存放在这里)
WebView 结构
- 第一阶段是启动一个 WebView,在iOS和 Android 系统上,操作系统启动WebView都需要一小段时间。
- 第二阶段是在 WebView 中初始化基础库,此时还会进行一些基础库内部优化,以提升页面渲染性能。
- 第三阶段是注入小程序 WXML 结构和 WXSS 样式,使小程序能在接收到页面初始数据之后马上开始渲染页面(这一阶段无法在小程序启动前执行)。
- 每一个页面都独立运行在一个页面层级上。小程序启动时仅有一个页面层级,每次调用
wx.navigateTo
,都会创建一个新的页面层级,wx.navigateBack
会销毁一个页面层级。
- 微信开发者工具底层是 Chrome XWeb 内核,进行开发跨平台的桌面应用(如QQ、WeChat客户端)。
- 左上角选择,
微信开发者工具 -> 调试 -> 调试微信开发者工具
,和谷歌调试界面几乎一模一样(利用这个工具,我们后续可以处理一些内部报错的调试BUG)。 - 接下来,我们利用脚本遍历开发工具的 webview 元素。
// 获取所有的 webview
document.getElementsByTagName('webview')// 打开调试的 webview
document.getElementsByTagName('webview')[0].showDevTools(true, null)
- webview 的含义如下:当前小程序的页面 两个渲染层 逻辑层 调试器
- 新开一个页面就会新增一个 webview,微信限制最多10个以保证性能问题的底层原因
- 利用命令打开一个 webview 页面进行具体的调试
- 页面的样式、调试库、渲染库、开发工具的配置…
- body 下面的标签就是利用 小程序开发的 Exparser 框架将 dom 转换为自定义组件的一套规则
- 每个 webview 都加载了这么多文件,是如何保证高效运作的?
快速渲染 PageFrame
- 利用 page frame 模板生成 webview 视图。
- 基本的 webview 模板和之前打开的一致,但是包含一些注释占位符,后续会被编译为具体的执行 js 文件。
加载流程如下:
- 首页启动时,即第一次通过
pageframe.html
生成内容后,后台服务会缓存pageframe.html
模板首次生成的html内容。- 非首次新打开页面时,页面请求的
pageframe.html
内容直接走后台缓存。 - 非首次新打开页面时,
pageframe.html
页面引入的外链js资源(如上图所示)走本地缓存。
- 非首次新打开页面时,页面请求的
- 生成 webview 模板后,初始化 webview 地址
http://127.0.0.1:${global.proxyPort}/aboutblank?${c}
空地址,其中${c}
为对应 webview 的 id。 - 监听页面的 ready 操作,注入执行代码脚本生成最终的 webview 地址和执行代码。
编译原理
基础语法不作过多赘述,主要编译原理和rpx动态适配。WXSS/WXML
并不可以直接执行在webview
层进行渲染,通过wcsc/wcc
执行脚本编译为js文件,然后注入webview中,这里可以演示一下。
// help() 查看编译命令
help()// 编译 WXSS 命令
./wcsc -js index.wxss >> style.js// 编译 WXML 命令
./wcc -js index.wxml >> test.js// 执行 $gwx 文件
var decodeName = decodeURI("./pages/home-tab/index.wxml")
var generateFunc = $gwx(decodeName)generateFunc()
var eps = 1e-4
var transformRPX =window.__transformRpx__ ||function (number, newDeviceWidth) {if (number === 0) return 0number = (number / BASE_DEVICE_WIDTH) * (newDeviceWidth || deviceWidth)number = Math.floor(number + eps)if (number === 0) {if (deviceDPR === 1 || !isIOS) {return 1} else {return 0.5}}return number}
-
wcsc 将 WXSS 编译为 JS 文件。
-
JS 文件注入到 WebView 中。
-
逻辑层执行 JS 文件,主要是设备信息获取(宽度、高度、横屏)、特定规则 rpx 适配为 px,写入编译后的 CSS 文件到 head style 头部。
-
WCC 将 WXML 编译为 JS 文件。
-
但是文件作了压缩混淆,本质逻辑执行
$gwx
函数。 -
generateFunc
就是接受动态数据,并生成虚拟 DOM 树的函数,DOM 树已存在的数据直接渲染为 wx-view/wx-text,需要 JS 脚本异步获取的数据采取 tag: virtual 虚拟 DOM 元素进行占位,等到获取后端数据之后直接填充 => 真实 DOM。
Exparser
WebComponents Shadow Dom
Exparser是微信小程序的组件组织框架,内置在小程序基础库中,为小程序提供各种各样的组件支撑。内置组件和自定义组件都有Exparser组织管理。
这部分后面单独抽离一篇文章进行讲解…
通讯系统
在正式讲解小程序的通讯系统前,先来熟悉一下小程序的 发布 - 订阅模式
美团一面:你了解发布-订阅模式吗?「每天搞透一道JS手写题💪Day8」 - 掘金
概述:引入中间平台进行注册和通知,有效解决了观察者维护列表导致的解耦不彻底问题
观察者通过 on 向 EventBus 注册事件,然后 Subject 通过 emit 向 EventBus 发射事件,由 EventBus 来向观察者更新。本质上是维护一个 events 对象,通过事件名注入到 events,每个 事件名 里面都有相应的回调函数,发布之后会分发到相应事件 回调函数 的方法。
class PubSub {constructor() {this.events = {};}subscribe(event, callback) {if (typeof event !== 'string') {throw new Error('Event name must be a string');}if (typeof callback !== 'function') {throw new Error('Callback must be a function');}if (!this.events[event]) {this.events[event] = [];}this.events[event].push(callback);}unsubscribe(event, callback) {if (typeof event !== 'string') {throw new Error('Event name must be a string');}if (typeof callback !== 'function') {throw new Error('Callback must be a function');}if (!this.events[event]) return;this.events[event] = this.events[event].filter(cb => cb !== callback);}publish(event, data) {if (typeof event !== 'string') {throw new Error('Event name must be a string');}if (!this.events[event]) return;this.events[event].forEach(callback => callback(data));}
}
在微信小程序执行过程中,Native层(客户端层)分别向渲染层与逻辑层注入 WeixinJSBridge 以达到线程通讯的目的,前面也提到了 webview 脚本注入的原理,WeixinJSBridge 提供了如下几个方法:
- invoke - 调用 Native API,以api方式调用开发工具提供的基础能力,并提供对应api执行后的回调
- invokeCallbackHandler - Native 传递 invoke 方法回调结果
- on - 用来收集小程序开发者工具触发的事件回调
- publish - 渲染层发布消息,用来向逻辑业务层发送消息,也就是说要调用逻辑层的事件方法
- subscribe - 订阅逻辑层消息
- subscribeHandler - 视图层和逻辑层消息订阅转发
- setCustomPublishHandler - 自定义消息转发
- WXML 渲染为虚拟 DOM,添加
addEventListener
进行事件解析。 - 逻辑层解析的时候会利用 JSBridge subscribe 订阅事件名称到渲染层,执行逻辑还在逻辑层,只是把名称和具体代码在渲染层作了映射。
- 触发事件,渲染层发布消息 publish 携带方法名经过 JSBridge 到达逻辑层。
- 逻辑层执行将 Data 以 JSON 字符串格式的数据经过 JSBridge 渲染给 WXML。
生命周期
onLaunch(App onLaunch)
App 主应用开始初始化,逻辑线程开始执行。onLoad(Object query)
页面加载时触发,一个页面只会调用一次,可以在onLoad的参数中获取打开当前页面路径中的参数。onShow()
页面显示/切入前台时触发。onHide()
页面隐藏/切入后台时触发。如wx.navigateTo
或底部 tab 切换到其他页面,小程序切入后台等。onReady()
页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。onUnload()
页面卸载时触发。如wx.redirectTo
或wx.navigateBack
到其他页面时。
wx.navigateTo
方式是创建新的webview
(添加新的页面栈,新加入的页面从头渲染,之前的页面onHide
隐藏,为了使用navigateBack
走缓存onShow
)。wx.redirectTo
以及wx.navigateBack
是通过更新自身webview
进行页面转换的,所以当前页面会进行卸载操作,并且重新生成新页面。
基础库解包
微信开发者工具里面选择的基础库为微信中的基础库版本(后面标识了兼容性和用户的数量),可用于微信开发者工具内的调试。每个版本的微信客户端都会自带一个版本的小程序基础库,而不是微信客户端带着所有版本的基础库,所以开发时选择的版本尽量和客户端的一致(最新的为好),避免 API 兼容性问题。
接下来,我们利用 openVendor() 找到 基础库进行解析,找到原始的 wxvpkg 然后利用 Github 工具进行反编译出源码,https://github.com/csj5588/wxappUnpacker
构建后的结果在 dist 文件下,本质上还是渲染层和逻辑层两个线程脚本之间的交互流程,后续在深入探讨。
跨端框架
由于小程序语法较为原始,工程化工具不支持,市面上太多平台的小程序需要适配开发,基于此市面上的第三方框架也慢慢进入大众的视野,目前来说流行的就是 taro 和 uni-app。
下面先来介绍下框架的分类:
预编译
本质上是利用 DSL(语法规则) + 语法解析,将一些逻辑转换为小程序支持的语法,但是这样存在一些问题:
- 如果React或者Vue后期再出一些新特性的话,预编译框架都需要进行语法解析扩展编写。
- 兼容问题,比如小程序不支持的一些属性,如果不支持,预编译框架要进行兼容。
半编译半运行
基本上运行时的框架都是参考Vue的框架才可以达到运行时的目的,注意小程序是不支持直接操作DOM元素的,所以只需要将Vue的patch挂载真实DOM流程修改为小程序setData的逻辑,template转换为WXML,style适配下规则就可以。
mpvue
(github地址请参见)是一个使用Vue.js开发小程序的前端框架。框架基于Vue.js
核心,mpvue
修改了Vue.js的runtime和compiler实现,使其可以运行在小程序环境中,从而为小程序开发引入了整套Vue.js
开发体验。
下面我们来看一下源码是如何实现的?
- 修改了 vue 的 patch 阶段进行
this.$updateDataToMP()
方法。 - 在
this.$updateDataToMP()
方法就进行了setData
的一个调用,还进行了diffData
数据的比对和throttle
函数优化双线程通讯的性能。
运行时框架
运行时框架主要解决需要 template 转换为 WXML 这部分逻辑,这部分可以借助小程序的template
模版机制来进行解决。
这样的话我们只需要进行 root 数据的操作即可,操作完成后利用 setData 渲染机制 发送到渲染层进行操作即可,Taro4 我看编译的结果似乎也是按照这样的格式操作的,后续再看看。
主流技术
Taro
Taro 介绍 | Taro 文档
Taro 特点总结
- 采用 TypeScript (TS) 加上部分 Rust 进行开发
- 底层标准参考 微信小程序,兼容性较好,其他平台的兼容性未知
- 对 React 和 Webpack 语法有良好的兼容性支持,Vue 3 加上 Vite 新推出,也可以用
- 调试开发需要下载不同平台的工具,无法直接导出运行
- 在 GitHub 上搜索近两年 stars 30+ 的开源项目,资源只有一页,显示资源较少
- 不支持使用 Vue 3 的 scoped CSS 样式隔离语法,这可能需要更详细的介绍
资源链接
Taro UI | O2Team
NutUI - 移动端组件库
组件库选择建议
- Taro 组件库:由 Taro 维护,但不推荐安装
- NutUI 组件库:多端组件库分离,推荐作为开发的首选
uni-app
uni-app官网
相关资源链接
- uview-plus 3.0 - 全面兼容nvue的uni-app生态框架 - uni-app UI框架
- GitHub - Moonofweisheng/wot-design-uni: 一个基于Vue3+TS开发的uni-app组件库,提供70+高质量组件,支持暗黑模式、国际化和自定义主题。
- 页面 | uni-app官网
uni-app 特点总结
本质上有两种体系:
- 一种是 uniapp + HBuilder 工具构建的一套自己的规范,其中包含:uts(TypeScript 超集)、uni-modules (依赖管理)、uvue(编译语言)、uniCloud(云服务),最终这些被 uni-app x 统一集成,需要重新学习一套标准、时间成本和难度过高,编辑器也不如前端常用的编辑器 VSCode、WebStorm
- 另一种可以借助原本的命令行执行,和其他的前端项目一致,可以借助第三方优质模板,但是注意 app 部分打包仍然需要 HBuilder 开发工具(推荐)
汇总
维度 | Taro | 得分 | Uni-app | 得分 |
---|---|---|---|---|
社区文档 | 清晰明确 | 8 | 较为混乱、自有体系和前端不兼容 | 6 |
上手成本 | VUE 版本上手容易、React 较高 | 8 | 底层采用 VUE 开发,熟悉程度更高 | 9 |
开源项目 pushed:>2023-09-01 stars:>30 | 68 | 7 | 143 | 10 |
Github 活跃 | stars:35.3k+ issues:1.2k + 1w+ | 10 | stars:39.9k+ issues:0.9k + 3k+ | 8 |
三方组件库 | 官方组件库统一,资源优质 NutUI VUE 6k+ | 9 | 官方组件库较为简陋、社区UI生态较差、大部分收费、一部分不敢用 | 5 |
TS 支持 | 兼容性优秀 | 9 | 兼容性优秀 | 8 |
VUE 语法兼容 | 兼容大部分 VUE 语法 | 7 | 兼容大部分 VUE 语法 | 8 |
React 语法兼容 | 支持 | 0 | 不支持 | 0 |
总计 | 🥇🏅🎖️ | 58 | 54 |
跨端开发框架深度横评
下周安排
开源商城项目拆解
- 腾讯有数
- gz-yami - Overview
- EastWorld
相关文章:

【小程序 - 大智慧】深入微信小程序的核心原理
目录 课程目标背景双线程架构WebView 结构快速渲染 PageFrame编译原理Exparser通讯系统生命周期基础库解包跨端框架预编译半编译半运行运行时框架 主流技术Tarouni-app汇总 下周安排 课程目标 本次课程主要通过后台管理小程序回顾一下小程序的高阶语法,然后讲解整体…...

Qt 去掉QDialog对话框的问号
QT 对话框的问号是什么? QDialog默认的window flag中包含了Qt::WindowContextHelpButtonHint,这个flag意思是在窗口上提供“上下文帮助”按钮 使用方式/调用方式 void QWidget::setWhatsThis(const QString &)比如: ui->lineEdit_1->setWh…...

负载均衡 Ribbon 与 Fegin 远程调用原理
文章目录 一、什么是负载均衡二、Ribbon 负载均衡2.1 Ribbon 使用2.2 Ribbon 实现原理 (★)2.3 Ribbon 负载均衡算法 三、Feign 远程调用3.1 Feign 简述3.2 Feign 的集成3.3 Feign 实现原理 (★) 一、什么是负载均衡 《服务治理:Nacos 注册中心》 末尾提到了负载均…...
c/c++:CMakeLists.txt中添加编译/连接选项使用内存错误检测工具Address Sanitizer(ASan)
Address Sanitizer(ASan)是一个快速的内存错误检测工具。从gcc 4.8开始,AddressSanitizer成为gcc的一部分。 既然是gcc内置的内存检查工具,用起来比第三方的库更方便些。只要指定相应的编译链接参数就可以实现内存泄露检查了,如下是是cmake脚…...

armbian cups 远程打印机 1022
使用 CUPS Web 浏览器界面设置和管理打印机 - Oracle Solaris 管理:常见任务 N1刷armbian变身打印服务器,支持全平台无线打印PC扫描_存储设备_什么值得买 (smzdm.com) 第 6 章 使用 Web 界面向 CUPS 添加打印机 | Red Hat Product Documentation apt…...
three.js使用3DTilesRendererJS加载3d tiles数据
原生的 three.js 目前不支持 3d tiles 数据的加载,不过开源社区已经给出了一些解决方案,其中最活跃的要属 3DTilesRendererJS。它为 three.js 提供了加载和调度 3d tiles 数据的基本能力,虽说和 Cesium.js 对 3d tiles 的支持相比还有很大的差…...

坐牢第三十五天(c++)
一.作业 1.使用模版类自定义栈 代码: #include <iostream> using namespace std; template<typename T> // 封装一个栈 class stcak { private:T *data; //int max_size; // 最大容量int top; // 下标 public:// 无参构造函数stcak();// 有参…...

Conda离线部署django
要在没有网络连接的环境中使用conda部署Django,你需要预先在有网络连接的机器上创建一个包含所有必要包的环境,并导出该环境的配置文件。然后,你可以将这个配置文件和必要的包传输到目标机器上进行安装。 下面是详细的步骤: 1. …...
1. Fabric.js安装使用
安装 # 安装 fabricjs npm i fabric --save在需要使用的页面引入 import * as fabric from fabric...
Excel中.xls和.xlsx文件格式的区别,及C++操作Excel文件
文件结构和兼容性: XLS是Excel 97-2003版本的文件格式,而XLSX是Excel 2007及以上版本的文件格式。XLS格式是向下兼容的,意味着较新的Excel版本可以打开XLS文件,但较旧的版本无法打开XLSX文件。相反,XLSX格式是向上…...
php实用命令
php相关命令 命令错误级别 命令 命令命令介绍具体用法php -v查看php版本php -vphp -l检查php文件是否有语法错误php -lphp -m查看当前php安装的扩展php -mphp -i | grep extension_dir查看扩展安装的目录php -i | grep extension_dir 错误级别 命令命令介绍具体用法error_re…...

TypeError:未绑定方法
TypeError: unbound method 错误通常发生在类方法被调用时,但没有正确绑定到实例。这通常意味着你试图在类本身上调用一个实例方法,或者没有使用正确的方式创建类实例。 1、问题背景 某位开发者在尝试创建一个类似于经典的 Pratt 递归下降解析器时遇到了…...
Java虚拟机(JVM)的架构和工作原理,字节码执行流程
JVM的概念 JVM是Java Virtual Machine的缩写, 即Java虚拟机,也被称为Java程序运行的核心环境 。它是一种用于计算设备的规范,通过在实际的计算机上仿真模拟各种计算机功能来实现。JVM由一套字节码指令集、一组寄存器、一个栈、一个…...
416.分割等和子集
416.分割等和子集 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 示例 1: 输入:nums [1,5,11,5] 输出:true 解释:数组可以分割成 [1, 5, 5] 和…...
python初始化一个三维数组
文章目录 1.什么是三维数组2.那我应该如何初始化一个自定义长度的三维数组呢? 1.什么是三维数组 从最外层开始理解,可以理解为一维数组,里面套了一个二维数组(12等于三维数组) arr [ [[], []], [[], [], []], [[],[]]…...
EI会议推荐-第二届大数据与数据挖掘国际会议(BDDM 2024)
第二届大数据与数据挖掘国际会议(BDDM 2024) 1、基本信息 大会官网:http://www.icbddm.org/ 官方邮箱:icbddm163.com 主办方:武汉纺织大学 会议时间:2024年12月13日-12月15日 会议地点:湖…...
RK3566/RK3568 Android 11 动态显示/隐藏下拉框
概述 在系统服务中增加显示/隐藏状态栏方法,在上层app动态调用显示/隐藏下拉框方法,设备关机和重启后也能继续生效。 创建全局变量 1.定义全局变量 在frameworks/base/core/java/android/provider/Settings.java中添加 /*** Disable drop-down box* @hide*/public static…...

Android图片缓存工具类LruCache原理和使用介绍
LruCache & DiskLruCache原理。 常用的三级缓存主要有LruCache、DiskLruCache、网络,其中LruCache对应内存缓存、 DiskLruCache对应持久化缓存。Lru表示最近最少使用,意思是当缓存到达限制时候,优先淘汰近 期内最少使用的缓存,…...
生活杂记1
生命中,总有一些事需要你一生去治愈,我把这些杂记写出来,写完了就不再想了,太内耗了…hahaha~ 因为嘴馋,小时候经常去老姑家,她家有各类零食及平时很少吃的“山珍海味”。去的次数多了,就和她家…...
go常用代码
连接阿波罗: 默认properties类型 package mainimport ("fmt""github.com/apolloconfig/agollo/v4""github.com/apolloconfig/agollo/v4/env/config" )func main() {c : &config.AppConfig{AppID: "2222",Cl…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...