【Android】四大组件(Activity、Service、Broadcast Receiver、Content Provider)、结构目录
文章目录
- Android系统架构
- Android四大组件
- Activity
- Service
- Broadcast Receiver
- Content Provider
- 两大视图
- 主要结构目录
Android系统架构
https://blog.csdn.net/xzzteach/article/details/140904613
Android四大组件
Activity
- 一个 Activity 包含了用户能够看到的界面,从而于用户进行交互。一个应用程序中可以有零个或者多个Activity。零个 Activity 就表示,这个应用程序不包含与用户交互的界面。
- Android应用中每一个Activity都必须要在AndroidManifest.xml配置文件中声明注册,否则系统将不识别也不执行该Activity。
<activityandroid:name=".MainActivity"android:exported="true"android:label="@string/app_name"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>
- Activity的生命周期
Android 是使用任务(task)来管理Activity的,一个任务就是一组存放在栈里Activity的集合,这个栈也叫作返回栈。Activity的生命周期由以下几个部分组成:
函数 | 描述 |
---|---|
onCreat() | 一个Activity启动后第一个被调用的函数,常用来在此方法中进行Activity的一些初始化操作。例如创建View,绑定数据,注册监听,加载参数等。 |
onStart() | 当Activity显示在屏幕上时,此方法被调用但此时还无法进行与用户的交互操作。 |
onResume() | 英文词义简历、继续进行 这个方法在onStart()之后调用,也就是在Activity准备好与用户进行交互的时候调用,此时的Activity一定位于Activity栈顶,处于运行状态。 |
onPause() | 这个方法是在系统准备去启动或者恢复另外一个Activity的时候调用,通常在这个方法中执行一些释放资源的方法,以及保存一些关键数据。 |
onStop() | 这个方法是在Activity完全不可见的时候调用的。 |
onDestroy() | 这个方法在Activity销毁之前调用,之后Activity的状态为销毁状态。 |
onRestart() | 当Activity从停止stop状态恢进入start状态时调用状态。 |
实际操作过程中,当打开启动Android应用时,MainActivity
会经过onCreate
-> onStart
-> onResume
三个阶段,此时若按home键或则back按键,MainActivity会经过onPause -> onStop
这两个阶段,再进入此MainActivity时,会再调用onRestart -> onStart -> onResume
三个阶段。
3、Activity 启动模式
启动模式一共有 4 中:standard
、singleTop
、singTask
和 singleInstance
,可以在 AndroidManifest.xml 中通过 标签指定 android:launchMode 属性来选择启动模式。
standard模式
standard 模式是 Activity 的默认启动模式,在不进行显示指定的情况下,所有 Activity 都会自动使用这种启动模式。对于使用 standard 模式启动的 Activity,系统不会在乎这个 Activity 是否已经存在在栈中了。每次启动的时候都会创建一个新的实例。一般用于打开邮件之类的。
- 下图为生成的默认Empty Activity
singleTop模式 (栈顶复用模式)
如果 Activity 指定为 singleTop,在启动 Activity 的时候发现返回栈的栈顶已经是该 Activity 了。则认为可以直接使用它,就不会再创建新的 Activity 实例了。因为不会创建新的 Activity 实例,所以 Activity 的生命周期就没有什么变化了。假设你在当前的Activity中又要启动同类型的Activity,此时建议将此类型Activity的启动模式指定为SingleTop,能够降低Activity的创建,节省内存!
一般用于登录页面,新闻详情页等。
singTask 模式(栈内单例模式)
singleTop 很好的解决了重复创建栈顶 Activity 的问题。如果 Activity 没有处于栈顶的位置,还是可能会创建多个 Activity 实例的。那就需要借助 singleTask 了。当 Activity 的启动模式为 singleTask 的时候,每次启动该 Activity 的时候系统会首先在返回栈中检查是否存在该 Activity 的实例,如果发现已经存在则直接使用该实例。并把这个 Activity 之上的所有 Activity 全部出栈,如果没有就会创建一个新的 Activity 实例。
一般主页面使用,购物页面,付款页面,浏览器主页等
- 下图为uniapp
singleInstance模式(堆内单例模式)
singleInstance 模式的 Activity 会启用一个新的返回栈来管理这个 Activity 。在这种模式下会有一个单独的返回栈来管理这个 Activity,不管是哪个应用程序来访问这个 Activity,都共用的同一个返回栈,也就解决了共享 Activity 实例的问题。
4、Activity 之间相互跳转及通信
Intent(意图)是应用程序种各个组件联系的桥梁,通信的载体,负责应用程序中数据的传递。
- 不带数据跳转
Intent intent = new Intent(this,MainActivity.class);
startActivity(intent);
此段代码实现从当前Activity,跳转到MainActivity,不带任何参数。
- 带数据或多个数据跳转
//带数据跳转
String data = "是我主活动调用了你";
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("ext", data);
startActivity(intent);
- 带数据跳转,带数据返回
Intent intent = new Intent(LoginActivity.this,RegisterActivity.class);
Bundle bundle = new Bundle() ;
bundle.putString("register","请开始注册!");
intent.putExtras(bundle) ;
startActivityForResult(intent,1);
在跳转时使用startActivityForResult方法,此方法传入两个参数一个是Intent ,另外一个是给当前请求设置的一个请求ID,此ID在结束数据时辨识是否使当前请求的返回结果。
同时要在跳转源Activity中实现 onActivityResult 方法来接收处理目的Activity返回的数据。
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);switch (requestCode) {case 1:if (resultCode == RESULT_OK) {final EditText loginUsername = findViewById(R.id.username);String returnUsername = data.getStringExtra("userName");//序列化方式取出实体User user = (User)data.getSerializableExtra("user");loginUsername.setText(returnUsername);loginUsername.setSelection(returnUsername.length());}break;default:}
}
- Intent隐式实现启动其他程序Activity
在当前Activity中调用百度请求界面。
Uri uri = Uri.parse("https://www.baidu.com");
Intent it = new Intent(Intent.ACTION_VIEW, uri);
startActivity(it);
直接调用打电话功能
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("tel:13207690000"));
startActivity(i);
在使用系统电话功能时需要给当前应用程序授权,在AndroidManifest.xml文件中增加
<uses-permission android:name="android.permission.CALL_PHONE" />
打开地图界面
Uri uri = Uri.parse("geo:38.899533,-77.036476");
Intent it = new Intent(Intent.ACTION_VIEW, uri);
startActivity(it);
Service
- Service简单介绍
- Service它可以在后台执行长时间运行操作而没有用户界面的应用组件,不依赖任何用户界面,例如后台播放音乐,后台下载文件等。
- 虽然服务是在后台运行的,但是Service和Activity都是运行在当前APP所在的main thread(UI主线程)中的,而耗时操作(如网络请求、拷贝数据、大文件)会阻塞主线程,给用户带来不好的体验。如果需要在服务中进行耗时操作,可以选择 IntentService,IntentService是Service的子类,用来处理异步请求。
- Service启动的两种方式
startService()
在Acitivity界面通过显式意图(或隐式意图)的方式来启动服务和关闭服务。
Intent intentService = new Intent(MainActivity.this, AudioServiceOnBind.class);
startService(intentService);
生命周期顺序:onCreate->onStartCommand->onDestroy
onCreate() 当Service第一次被创建时调用。
onStartCommand() 当startService方法启动Service时,该方法被调用。
onDestroy() 当Service不再使用时调用。
bindService()
绑定服务
当应用组件通过调用 bindService() 绑定到服务时,服务即处于“绑定”状态。绑定服务提供了一个客户端-服务器接口,允许组件与服务进行交互、发送请求、获取结果。 仅当与另一个应用组件绑定时,绑定服务才会运行。 多个组件可以同时绑定到该服务,但全部取消绑定后,该服务即会被销毁。
首先在我们的服务中创建一个内部类AudioBinder继承Binder来获取当服务实例,然后在onBind方法中返回当前服务的实例。
public class AudioServiceOnBind extends Service implements MediaPlayer.OnCompletionListener{private final IBinder binder = new AudioBinder();//用于播放音乐等媒体资源private MediaPlayer mediaPlayer;public AudioServiceOnBind() {super();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.d(AudioServiceOnBind.this.getClass().getName(),"执行onStartCommand()");return 0;}@Overridepublic IBinder onBind(Intent intent) {return binder;}@Overridepublic void onCreate(){super.onCreate();Log.d(AudioServiceOnBind.this.getClass().getName(),"执行onCreate()");if (mediaPlayer==null){mediaPlayer=MediaPlayer.create(this,R.raw.gumeng);mediaPlayer.setOnCompletionListener(this);}mediaPlayer.start();}@Overridepublic void onCompletion(MediaPlayer mp) {stopSelf();}@Overridepublic void onDestroy(){if(mediaPlayer.isPlaying()){mediaPlayer.stop();}mediaPlayer.release();stopForeground(true);Log.d(AudioServiceOnBind.this.getClass().getName(),"执行onDestroy()");}//为了和Activity交互,我们需要定义一个Binder对象class AudioBinder extends Binder {//返回Service对象AudioServiceOnBind getService(){return AudioServiceOnBind.this;}}}
然后在调用的Activity中创建一个ServiceConnection对象重写其中的onServiceConnected方法获取所要绑定的服务。在触发事件的方法中调用bindService实现服务的最终绑定。
public class MainActivity extends AppCompatActivity {private AudioServiceOnBind audioServiceOnBind;//使用ServiceConnection来监听Service状态的变化private ServiceConnection conn = new ServiceConnection() {@Overridepublic void onServiceDisconnected(ComponentName name) {audioServiceOnBind = null;}@Overridepublic void onServiceConnected(ComponentName name, IBinder binder) {//这里我们实例化audioService,通过binder来实现audioServiceOnBind = ((AudioServiceOnBind.AudioBinder) binder).getService();}};public void click_music_open(View view) {Intent intentService = new Intent(MainActivity.this, AudioServiceOnBind.class);bindService(intentService, conn, Context.BIND_AUTO_CREATE);}
}
生命周期:onCreate->onBind->onUnBind->onDestroy
-
onCreate() 当Service被创建时,由系统调用。
-
onBind() 当bindService方法启动Service时,该方法被调用。
-
onUnbind() 当unbindService方法解除绑定时,该方法被调用。
-
onDestroy() 当Service不再使用时,由系统调用。
- 实现前台Service
Android 8.0 后系统不允许后台应用创建后台服务。 因此,Android 8.0 引入了一种全新的方法,即 Context.startForegroundService(),以在前台启动新服务。
在service onStartCommand方法中增加以下代码
@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.d(AudioServiceOnBind.this.getClass().getName(),"执行onStartCommand()");Intent nfIntent = new Intent(this, MainActivity.class);Notification.Builder builder = new Notification.Builder(this.getApplicationContext()).setContentIntent(PendingIntent.getActivity(this, 0, nfIntent, 0)).setSmallIcon(R.mipmap.touxiang).setContentTitle("wu").setContentText("Android测试").setWhen(System.currentTimeMillis());String CHANNEL_ONE_ID = "com.wu";String CHANNEL_ONE_NAME = "Channel One";//安卓8.1以上系统NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ONE_ID, CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_MIN);notificationChannel.enableLights(false);notificationChannel.setShowBadge(true);notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);manager.createNotificationChannel(notificationChannel);builder.setChannelId(CHANNEL_ONE_ID);Notification notification = builder.build();startForeground(1, notification);return super.onStartCommand(intent,flags,startId);}在调用Activity中调用startForegroundService方法。public void click_music_open(View view) {Intent intentService = new Intent(MainActivity.this, AudioServiceOnBind.class);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {startForegroundService(intentService);} else {startService(intentService);}}
- 使用IntentService
由于Service中的逻辑都是执行在主线程中的,此时如果在Service中处理一下耗时操作可能就会给用户带来不好的体验。所以此时就可以使用Android多线程Service.
本质上IntentService是在Service里开启线程去做任务处理。IntentService会在任务执行完成后自行结束自己,而不需要外部去调用stopService了。
使用IntentService定义的服务,要开启线程,只要重写一个onHandleIntent()方法就可以了,而且在运行完之后会自动停止。
例如数据下载 数据上传等。
public class MyIntentService extends IntentService {private static final String TAG = "MyIntentService";public MyIntentService() {super("MyIntentService");}@Overrideprotected void onHandleIntent(Intent intent) {Log.d(TAG, "当前是子线程: " + Thread.currentThread().getId());//在这里实现异步多线程处理逻辑//例如数据下载 数据上传等。Log.d(TAG, "我在后台默默下载数据中。。。。");}@Overridepublic void onCreate() {Log.d(TAG, "onCreate: ");super.onCreate();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {Log.d(TAG, "onStartCommand: ");return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {Log.d(TAG, "onDestroy: ");super.onDestroy();}
}
Broadcast Receiver
Content Provider
两大视图
- project
- android
主要结构目录
-
bulid
编译时自生成文件
-
libs
第三方jar包,会被自动添加到构建路径中去
-
java
java代码
-
res
项目中使用的所有资源,drawable存放图片,layout存放布局,values存放字符,mipmap存放图标
-
Manifest
AndroidManifest.xml配置文件,程序中定义的四大组件都需要在这个文件里注册,另外这个文件中还可以给应用程序添加权限声明
-
bulid.gradle
项目构建工具,通常有两个bulid.gradle,一个是项目级一个是app级
-
com.android.application
应用程序模块 -
com.android.library
库程序模块
区别:一个是可以直接运行的,一个只能作为代码库依附于别的应用程序模块来运行
相关文章:

【Android】四大组件(Activity、Service、Broadcast Receiver、Content Provider)、结构目录
文章目录 Android系统架构Android四大组件ActivityServiceBroadcast ReceiverContent Provider 两大视图主要结构目录 Android系统架构 https://blog.csdn.net/xzzteach/article/details/140904613 Android四大组件 Activity 一个 Activity 包含了用户能够看到的界面࿰…...
前端开发:创建可拖动的固定位置 `<div>` 和自动隐藏悬浮按钮
在前端开发中,实现一个可拖动的固定位置 <div>,并且根据拖动的状态控制其显示和隐藏,同时在特定条件下显示悬浮按钮,涉及以下技术和原理: 技术细节和实现步骤: 1. HTML 结构: <!DOC…...
Java Bean Validation 注解:@NotEmpty、@NotBlank 和 @NotNull 的区别
1. 概述 Bean Validation 是 Java 提供的一种对 Java Bean 实例的字段或方法参数进行校验的标准机制。它允许开发者使用注解的方式定义验证逻辑,这些注解可以在类、字段或者方法上声明,并且可以被任何实现了 JSR 303/JSR 349 规范的框架(如 …...

Java | Leetcode Java题解之第322题零钱兑换
题目: 题解: public class Solution {public int coinChange(int[] coins, int amount) {int max amount 1;int[] dp new int[amount 1];Arrays.fill(dp, max);dp[0] 0;for (int i 1; i < amount; i) {for (int j 0; j < coins.length; j)…...

Linux初启征程指南:攻克常见系统指令与权限初理解
有时候觉得,电脑就像一个高贵冷艳的妹纸。 400,是她冷冰冰地说:“我听不懂你在说什么”; 401,是她无情地转身:“我不认识你,别说那些奇怪的话”; 403,是她残酷的拒绝&…...

第十九节、野猪受伤死亡逻辑动画
一、协程 在这个代码中,update更新非常快,不会有时间去addforce增加力 所以需要使用协程,同时开启 1、写法 WaitForSeconds(0.45f) 意思是等待时间0.45秒后 写完协程程序后,需要开启 ,固定写法如下 2、注意 dir是局…...

vue 开发工具 Hbuilder 简介及应用
一、简介 HBuilderX 是一款流行的前端开发工具,由DCloud公司开发。它支持多种编程语言,如HTML、CSS、JavaScript、Vue、UniApp等,非常适合用来开发Web应用、移动端应用和跨平台应用。 官网地址:https://www.dcloud.io/hbuilderx.…...
【杂谈】-MQTT与HTTP在物联网中的比较:为什么MQTT是更好的选择
MQTT与HTTP在物联网中的比较:为什么MQTT是更好的选择 文章目录 MQTT与HTTP在物联网中的比较:为什么MQTT是更好的选择1、什么是MQTT2、什么是HTTP3、MQTT和HTTP之间的差异 MQTT(消息队列遥测传输)和HTTP(超文本传输协议…...
冠豪猪优化算法(CPO)、卷积神经网络(CNN)与支持向量机(SVM)结合的预测模型(CPO-CNN-SVM)及其Python和MATLAB实现
### 一、背景 在现代数据挖掘和机器学习领域,特征选择与模型优化是两个重要的研究方向。随着深度学习的发展,卷积神经网络(CNN)在图像、视频等多媒体数据处理中的表现优异。然而,传统的CNN模型通常需要大量的标注数据和…...
【通信原理】
通信原理 二、频谱与随机信号2.1 频谱2.1.1 频谱or频谱密度函数2.1.2 幅度谱(幅频特性)or相位谱(相频特性) 2.2 能量信号2.2.1 什么是能量信号2.2.2 巴塞瓦尔定理2.2.3 维纳钦辛定理 2.3 功率信号2.3.1 功率信号2.3.2 巴塞瓦尔定理…...
有序数组的平方(LeetCode)
题目 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 解题 以下算法时间复杂度为 def sortedSquares(nums):n len(nums)result [0] * n # 创建一个结果数组,长度与 nums 相同le…...
Python配置镜像
1. 查看当前源 pip config get global.index-url 2. 临时变更源 pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple 3. 永久变更源 清华(推荐速度最快) pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple 百…...

Python新手错误集锦(PyCharm)
# 自学Python,用Pycharm作环境。我这个手新到这时我学习的第一个编程软件,且本人专业是化学,以前对电脑最高级的使用是玩扫雷游戏。所以这里集合的错误都是小透明错误,大部分人请绕道。不断更新中...... 缩进错误 记住“indent”…...

CTFHUB-web-RCE-php://input
开启题目 网页显示源代码,判断如果参数以 php:// 开头,那么执行 include 函数将参数值作为文件包含进来。否则,输出字符串 Hacker 。 点击下面的 phpinfo 跳转之后发现了一个 php 版本页面 使用 file 查看 php://input, 感觉这个…...
Python网络爬虫核心面试题
网络爬虫 1. 爬虫项目中如何处理请求失败的问题?2. 解释HTTP协议中的持久连接和非持久连接。3. 什么是HTTP的持久化Cookie和会话Cookie?4. 如何在爬虫项目中检测并处理网络抖动和丢包?5. 在爬虫项目中,如何使用HEAD请求提高效率&a…...

DSL domain specific language of Kola
How we design Kola - ApiHugKola background, Kola a consumer driver tester frameworkhttps://apihug.com/zhCN-docs/kola/003_dsl_contract Concept 在 Kola 定位中 Kola 是什么, 是致力于提供一个让相关各方都能够理解共同创造的测试框架和工具。 同时 Kola 是建立于业界…...

【RISC-V设计-05】- RISC-V处理器设计K0A之GPR
【RISC-V设计-05】- RISC-V处理器设计K0A之GPR 文章目录 【RISC-V设计-05】- RISC-V处理器设计K0A之GPR1.简介2.设计顶层3.内部结构4.端口说明5.设计代码6.总结 1.简介 通用寄存器(General Purpose Register)是处理器设计中的重要组成部分,在…...

Linux/C 高级——shell脚本
1. shell脚本基础概念 1.1概念 shell使用方式:手动下命令和脚本 脚本本质是一个文件,文件里面存放的是特定格式的指令,系统可以使用脚本解析器翻译或解析指令并执行(它不需要编译)。 shell脚本本质:shell命…...

SpringBoot面试题整理(1)
面试整理 前置知识 ApplicationContextInitializerApplicationListenerBeanFactoryBeanDefinitionBeanFactoryPostProcessorAwareInitializingBean/DisposableBeanBeanPostProcessor 面试题 SpringBoot启动流程IOC容器初始化流程Bean声明周期Bean循环依赖SpringMVC执行流程…...

LVS原理及实例
目录 LVS原理 LVS概念 lvs集群的类型 lvs-nat 解释 传输过程 lvs-dr 解释 传输过程 特点 lvs-tun LVS(Linux Virtual Server)常见的调度算法 防火墙标记(Firewall Marking)结合轮询调度 实战案例 lvs的nat模式配置 …...
vue 多端适配之pxtorem
在 Vue 3 Vite 项目中使用 postcss-pxtorem 自动将 px 单位转换为 rem 单位,可以按照以下步骤配置: 一、基础版本 1. 安装依赖 首先安装必要的插件: npm install postcss postcss-pxtorem autoprefixer -D # 或 yarn add postcss postcs…...

我的概要设计模板(以图书管理系统为例)
一、总述 1.1 需求或目标 随着数字化阅读普及,传统图书馆管理方式效率低下、资源检索不便。为提升图书管理效率,方便读者借阅与查询,公司计划开发 “在线图书管理系统”,实现图书的电子化管理、快速检索、在线借阅等功能&#x…...

2025 5 月 学习笔记
计算高斯半径,用于生成高斯热图 这个的意义是什么 有什么作用? 14 核心意义:平衡定位精度与检测鲁棒性 在基于热图的目标检测方法(如CenterNet、CornerNet等)中,计算高斯半径的核心意义在于在精确…...

【黄金评论】美元走强压制金价:基于NLP政策因子与ARIMA-GARCH的联动效应解析
一、基本面:多因子模型解析黄金承压逻辑 1. 政策冲击因子驱动美元强势 通过NLP模型对关税政策文本进行情感分析,构建政策不确定性指数(PUI)达89.3,触发美元避险需求溢价。DSGE模型模拟显示,钢铁关税上调至…...

谷歌地图免费下载手机版
软件标签: 谷歌地图 谷歌卫星高清地图 下载链接:夸克网盘分享 手机地图 谷歌地图免费下载(google maps)是谷歌公司打造的手机高清电子地图。2024谷歌地图官方中文版能够直观的表达出世界各地的地点,在地图中能够清晰的了解到自身的定位,让…...
GQA(Grouped Query Attention):分组注意力机制的原理与实践《一》
GQA(Grouped Query Attention)是近年来在大语言模型中广泛应用的一种注意力机制优化方法,最初由 Google 在 2023 年提出。它是对 Multi-Query Attention (MQA) 的扩展,旨在平衡模型性能与计算效率。 🌟 GQA 是什么&…...
数据库操作-MySQL-4(JDBC编程)
JDBC:通过Java代码操作mysql数据库,数据库会提供一些API供我们调用 MySQL、Oracle、等API有差异,但是Java统一了所有接口,即JDBC; 原始api-驱动包(类似转接头)-统一的api-Java 驱动包࿱…...

WordPress 6.5版本带来的新功能
WordPress 6.5正式上线了!WordPress团队再一次为我们带来了许多新的改进。在全球开发者的共同努力下,WordPress推出了许多新的功能,本文将对其进行详细总结。 Hostease的虚拟主机现已支持一键安装最新版本的WordPress。对于想要体验WordPres…...

鸿蒙电脑会在国内逐渐取代windows电脑吗?
点击上方关注 “终端研发部” 设为“星标”,和你一起掌握更多数据库知识 10年内应该不会 用Windows、MacOS操作系统的后果是你的个人信息可能会被美国FBI看到,但绝大多数人的信息FBI没兴趣去看 你用某家公司的电脑系统,那就得做好被某些人监视的下场,相信…...
Ajax技术分析方法全解:从基础到企业级实践(2025最新版)
引言 Ajax技术自2005年正式命名以来,已支撑全球83%的Web应用实现异步交互。2025年最新数据显示,单页面应用(SPA)的Ajax请求密度已达日均120亿次/应用。本文将系统化解析Ajax分析方法论,涵盖从基础原理到企业级工程实践的完整技术栈。 一、Ajax技术架构解构 1.1 核心组件…...