diff --git "a/AdavancedPart/1.\347\203\255\344\277\256\345\244\215\345\256\236\347\216\260(\344\270\200).md" "b/AdavancedPart/1.\347\203\255\344\277\256\345\244\215\345\256\236\347\216\260(\344\270\200).md"
index bf052c89..1abe582f 100644
--- "a/AdavancedPart/1.\347\203\255\344\277\256\345\244\215\345\256\236\347\216\260(\344\270\200).md"
+++ "b/AdavancedPart/1.\347\203\255\344\277\256\345\244\215\345\256\236\347\216\260(\344\270\200).md"
@@ -18,7 +18,7 @@
在一般情况下,应用程序不需要创建`ClassLoader`对象,而是使用当前环境已经存在的`ClassLoader`。因为`Java`的`Runtime`环境在初始化时,其内部会创建一个`ClassLoader`对象用于加载`Runtime`所需的各种`Java`类。
每个`ClassLoader`必须有一个父类,在装载`Class`文件时,子`ClassLoader`会先请求父`ClassLoader`加载该`Class`文件,只有当其父`ClassLoader`找不到该`Class`文件时,子`ClassLoader`才会继续装载该类,这是一种安全机制。
-对于`Android`的应用程序,本质上虽然也是用`Java`开发,并且使用标准的`Java`编译器编译出`Class`文件,但最终的`APK`文件中包含的却是`dex`类型的文件。`dex`文件是将所需的所有`Class`文件重新打包,打包的规则不是简单的压缩,而是完全对`Class`文件内部的各种函数表、变量表等进行优化,并产生一个新的文件,这就是`dex`文件。由于`dex`文件是一种经过优化的`Class`文件,因此要加载这样特殊的`Class`文件就需要特殊的类装载器,这就是`DexClassLoader`,`Android SDK`中提供的D`exClassLoader`类就是出于这个目的。
+对于`Android`的应用程序,本质上虽然也是用`Java`开发,并且使用标准的`Java`编译器编译出`Class`文件,但最终的`APK`文件中包含的却是`dex`类型的文件。`dex`文件是将所需的所有`Class`文件重新打包,打包的规则不是简单的压缩,而是完全对`Class`文件内部的各种函数表、变量表等进行优化,并产生一个新的文件,这就是`dex`文件。由于`dex`文件是一种经过优化的`Class`文件,因此要加载这样特殊的`Class`文件就需要特殊的类装载器,这就是`DexClassLoader`,`Android SDK`中提供的`DexClassLoader`类就是出于这个目的。
总体来说,`Android` 默认主要有三个`ClassLoader`:
@@ -75,7 +75,7 @@ public class DexClassLoader extends BaseDexClassLoader {
}
```
注释说的太明白了,这里就不翻译了,但是我们并没有找到加载的代码,去它的父类中查找,
-因为家在都是从`loadClass()`方法中,所以我们去`ClassLoader`类中看一下`loadClass()`方法:
+因为加载都是从`loadClass()`方法中,所以我们去`ClassLoader`类中看一下`loadClass()`方法:
```java
/**
* Loads the class with the specified name. Invoking this method is
@@ -128,7 +128,7 @@ public class DexClassLoader extends BaseDexClassLoader {
if (clazz == null) {
ClassNotFoundException suppressed = null;
try {
- // 先检查父ClassLoader是否已经家在过该类
+ // 先检查父ClassLoader是否已经加载过该类
clazz = parent.loadClass(className, false);
} catch (ClassNotFoundException e) {
suppressed = e;
diff --git a/AdavancedPart/AOP.md b/AdavancedPart/AOP.md
index 3bcc633b..c6e0916a 100644
--- a/AdavancedPart/AOP.md
+++ b/AdavancedPart/AOP.md
@@ -11,4 +11,131 @@ AOP(Aspect Oriented Programing),面向切面编程。
而AOP,就是将各个模块中的通用逻辑抽离出来。
我们将这些逻辑视为Aspect(切面),然后动态地把代码插入到类的指定方法、指定位置中。
+一句话概括: 在运行时,动态的将代码切入到类的指定方法、指定位置上的编程思想就是面相切面的编程。
+
+
+一般而言,我们管切入到指定类指定方法的代码片段称为切面,而切入到哪些类、哪些方法则叫切入点。有了AOP,我们就可以把几个类共有的代码,抽取到一个切片中,等到需要时再切入对象中去,从而改变其原有的行为。
+
+
+### AOP的实现方式
+
+#### 静态AOP
+
+在编译器,切面直接以字节码的形式编译到目标字节码文件中。
+
+1. AspectJ
+AspectJ属于静态AOP,它是在编译时进行增强,会在编译时期将AOP逻辑织入到代码中。
+
+由于是在编译器织入,所以它的优点是不影响运行时性能,缺点是不够灵活。
+
+2. AbstractProcessor
+自定义一个AbstractProcessor,在编译期去解析编译的类,并且根据需求生成一个实现了特定接口的子类(代理类)
+
+#### 动态AOP
+1. JDK动态代理
+通过实现InvocationHandler接口,可以实现对一个类的动态代理,通过动态代理可以生成代理类,从而在代理类方法中,在执行被代理类方法前后,添加自己的实现内容,从而实现AOP。
+
+2. 动态字节码生成
+在运行期,目标类加载后,动态构建字节码文件生成目标类的子类,将切面逻辑加入到子类中,没有接口也可以织入,但扩展类的实例方法为final时,则无法进行织入。比如Cglib
+
+CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。
+
+3. 自定义类加载器
+在运行期,目标加载前,将切面逻辑加到目标字节码里。如:Javassist
+
+Javassist是可以动态编辑Java字节码的类库。它可以在Java程序运行时定义一个新的类,并加载到JVM中;还可以在JVM加载时修改一个类文件。
+
+4. ASM
+ASM可以在编译期直接修改编译出的字节码文件,也可以像Javassit一样,在运行期,类文件加载前,去修改字节码。
+
+
+
+### AOP核心概念
+
+###### 1.JoinPoint(连接点)
+
+程序执行过程中可以被“插入”的点。例如:
+
+- 方法被调用时
+- 方法执行时
+- 构造函数被调用时
+- 字段被读取/赋值时
+- 异常抛出时
+
+
+###### 2.PointCut(切点)
+
+对JoinPoint的筛选规则,告诉AOP“我要在哪些点下手”。
+
+例如: 所有Activity的onCreate方法就是一个切点。
+
+###### 3. Advice(通知/增强)
+
+在切点处要执行的代码。分5种:
+
+- @Before: 切点执行前
+- @After: 切点执行后(无论成功失败)
+- @AfterReturning: 切点正常返回后
+- @AfterThrowing: 切点抛出异常后
+- @Around: 包裹切点(最强大,可控制是否执行原方法)
+
+###### 4. Aspect(切面)
+
+切点 + 通知 = 切面
+
+一个Java类用@Aspect标记后就是切面。
+
+##### 5. Weaving(织入)
+
+把切面代码插入到目标代码中的过程。 织入时机有三种:
+
+- 编译期织入(AspectJ主流方式)
+- 类加载期织入
+- 运行期织入(JDK/CGLIB动态代理,Spring用的多)
+
+###### 6. Target(目标对象)
+
+被切面影响的对象
+
+
+### AOP在Android的实现原理
+
+###### Java/Spring的AOP vs Android的AOP
+
+Spring主要用运行时动态代理(JDK Porxy/ CGLIB),但Android由于:
+
+- ART/Dalvik虚拟机限制
+- 性能要求高,运行时反射代价大
+- 类加载机制不同
+
+所以Android几乎都用AspectJ编译期自己码织入。
+
+###### 编译期织入原理
+
+
+```
+ ┌─────────────┐ javac ┌─────────────┐ ajc(AspectJ) ┌──────────────┐
+ │ .java │ ──────────> │ .class │ ──────────────> │ 织入后.class │
+ └─────────────┘ └─────────────┘ └──────────────┘
+ ↑
+ ┌─────────────┐
+ │ Aspect.java │
+ └─────────────┘
+```
+
+ajc(AspcetJ Compiler)会:
+
+1. 扫描所有.class,找匹配切点的位置
+2. 按通知类型,在该位置直接修改字节码插入代码
+3. 输出新的.class
+
+这意味着: AOP的开销在编译期,运行期几乎无额外开销(仅多几行字节码)。
+
+
+
+
+
+
+
+
diff --git a/AdavancedPart/ARouter.md b/AdavancedPart/ARouter.md
new file mode 100644
index 00000000..f9d9cc9f
--- /dev/null
+++ b/AdavancedPart/ARouter.md
@@ -0,0 +1,71 @@
+ARouter
+---
+
+
+[ARouter](https://github.com/alibaba/ARouter)
+一个用于帮助 Android App 进行组件化改造的框架 —— 支持模块间的路由、通信、解耦
+
+
+
+
+```java
+Intent intent = new Intent(mContext, XxxActivity.class);
+intent.putExtra("key","value");
+startActivity(intent);
+
+Intent intent = new Intent(mContext, XxxActivity.class);
+intent.putExtra("key","value");
+startActivityForResult(intent, 666);
+```
+在未使用ARouter路由框架之前的原生页面跳转方式。
+
+
+## 原生路由方案的缺点
+
+1. 显式: 直接的类依赖,耦合严重
+2. 隐式: 会在Manifest文件中进行集中管理,写作困难
+
+
+## ARouter的优势
+
+1. 使用注解,实现了映射关系自动注册与分布式路由管理
+2. 编译期间处理注解,并生成映射文件,没有使用反射,不影响运行时性能
+3. 映射关系按组分类,分级管理,按需初始化。
+4. 灵活的降级策略,每次跳转都会回调跳转结果,避免startActivity()一旦失败会抛出异常
+5. 自定义拦截器,自定义拦截顺序,可以对路由进行拦截,比如登录判断和埋点处理
+6. 支持依赖注入,可单独作为依赖注入框架使用,从而实现跨模块API调用
+7. 支持直接解析标准url进行跳转,并自动注入参数到目标页面中
+8. 支持多模块使用,支持组件化开发
+
+
+
+## 基本使用
+
+添加依赖并初始化后的基本使用:
+
+```java
+// 在支持路由的页面上添加注解(必选)
+// 这里的路径需要注意的是至少需要有两级,/xx/xx
+@Route(path = "/test/activity")
+public class YourActivity extend Activity {
+ ...
+}
+
+// 1. 应用内简单的跳转(通过URL跳转在'进阶用法'中)
+ARouter.getInstance().build("/test/activity").navigation();
+
+// 2. 跳转并携带参数
+ARouter.getInstance().build("/test/1")
+ .withLong("key1", 666L)
+ .withString("key3", "888")
+ .withObject("key4", new Test("Jack", "Rose"))
+ .navigation();
+```
+
+
+
+
+
+
+
+
diff --git "a/AdavancedPart/Android\345\220\257\345\212\250\346\250\241\345\274\217\350\257\246\350\247\243.md" "b/AdavancedPart/Android\345\220\257\345\212\250\346\250\241\345\274\217\350\257\246\350\247\243.md"
index 6c5ef656..5008840f 100644
--- "a/AdavancedPart/Android\345\220\257\345\212\250\346\250\241\345\274\217\350\257\246\350\247\243.md"
+++ "b/AdavancedPart/Android\345\220\257\345\212\250\346\250\241\345\274\217\350\257\246\350\247\243.md"
@@ -31,18 +31,21 @@ Android启动模式详解
- `singleInstance`
顾名思义,是单一实例的意思,即任意时刻只允许存在唯一的`Activity`实例,而且该`Activity`所在的`task`不能容纳除该`Activity`之外的其他`Activity`实例!
-它与`singleTask`有相同之处,也有不同之处。
-相同之处:任意时刻,最多只允许存在一个实例。
-不同之处:
- - `singleTask`受`android:taskAffinity`属性的影响,而`singleInstance`不受`android:taskAffinity`的影响。
- - `singleTask`所在的`task`中能有其它的`Activity`,而`singleInstance`的`task`中不能有其他`Activity`。
- - 当跳转到`singleTask`类型的`Activity`,并且该`Activity`实例已经存在时,会删除该`Activity`所在`task`中位于该`Activity`之上的全部`Activity`实例;而跳转到`singleInstance`类型的`Activity`,并且该`Activity`已经存在时,
- 不需要删除其他`Activity`,因为它所在的`task`只有该`Activity`唯一一个`Activity`实例。
+它与`singleTask`有相同之处,也有不同之处。
+相同之处: 任意时刻,最多只允许存在一个实例。
+不同之处:
+- `singleTask`受`android:taskAffinity`属性的影响,而`singleInstance`不受`android:taskAffinity`的影响。
+- `singleTask`所在的`task`中能有其它的`Activity`,而`singleInstance`的`task`中不能有其他`Activity`。
+- 当跳转到`singleTask`类型的`Activity`,并且该`Activity`实例已经存在时,会删除该`Activity`所在`task`中位于该`Activity`之上的全部`Activity`实例;而跳转到`singleInstance`类型的`Activity`,并且该`Activity`已经存在时,不需要删除其他`Activity`,因为它所在的`task`只有该`Activity`唯一一个`Activity`实例。
-假设我们的程序中有一个Activity是允许其他程序调用的,如果想实现其他程序和我们的程序可以共享这个Activity的实例,应该如何实现呢?使用前面3种启动模式肯定是做不到的,因为每个应用程序都会有自己的返回栈,同一个Activity在不同的返回栈中入栈时必然创建了新的实例。而使用singleInstance模式就可以解决这个问题,在这种模式下,会有一个单独的返回栈来管理这个Activity,不管是哪个应用程序来访问这个Activity,都共用同一个返回栈,也就解决了共享Activity实例的问题。
-假设现在有FirstActivity、SecondActivity、ThirdActivity三个Activity, SecondActivity的启动模式是SingleInstance。
+假设我们的程序中有一个Activity是允许其他程序调用的,如果想实现其他程序和我们的程序可以共享这个Activity的实例,应该如何实现呢?
+
+使用前面3种启动模式肯定是做不到的,因为每个应用程序都会有自己的返回栈,同一个Activity在不同的返回栈中入栈时必然创建了新的实例。
+而使用singleInstance模式就可以解决这个问题,在这种模式下,会有一个单独的返回栈来管理这个Activity,不管是哪个应用程序来访问这个Activity,都共用同一个返回栈,也就解决了共享Activity实例的问题。
+
+假设现在有FirstActivity、SecondActivity、ThirdActivity三个Activity, SecondActivity的启动模式是SingleInstance。
现在FirstActivity 启动SecondActivity,SecondActivity再启动ThirdActivity。
然后我们按下Back键进行返回,你会发现ThirdActivity竟然直接返回到了FirstActivity,再按下Back键又会返回到SecondActivity,再按下Back键才会退出程序,这是为什么呢?其实原理很简单,由于FirstActivity和ThirdActivity是存放在同一个返回栈里的,当在ThirdActivity的界面按下Back键时,ThirdActivity会从返回栈中出栈,那么FirstActivity就成为了栈顶Activity显示在界面上,因此也就出现了从ThirdActivity直接返回到FirstActivity的情况。然后在FirstActivity界面再次按下Back键,这时当前的返回栈已经空了,于是就显示了另一个返回栈的栈顶Activity,即SecondActivity。最后再次按下Back键,这时所有返回栈都已经空了,也就自然退出了程序。
@@ -59,4 +62,4 @@ Android启动模式详解
---
- 邮箱 :charon.chui@gmail.com
-- Good Luck!
\ No newline at end of file
+- Good Luck!
diff --git "a/AdavancedPart/Componse\344\275\277\347\224\250.md" "b/AdavancedPart/Componse\344\275\277\347\224\250.md"
new file mode 100644
index 00000000..6a2f0449
--- /dev/null
+++ "b/AdavancedPart/Componse\344\275\277\347\224\250.md"
@@ -0,0 +1,130 @@
+Compose使用
+===
+
+传统 Android UI 开发采用命令式模型,即通过命令驱动视图变化:findViewById 查找控件、设置属性、处理交互逻辑。代码经常伴随着多个职责耦合在一起,结构混乱,易错难测。
+
+Compose 则采用声明式模型:界面即状态的函数表达。当状态改变时,对应的 Composable 自动重新组合(Recompose)并刷新界面。这种模式更贴近现代前端(如 React/Vue)的理念。
+
+无需关心视图更新逻辑,只要状态变化,界面自然重绘,大幅降低 UI 层复杂度。
+
+
+1.3 开发效率提升点
+
+代码量平均减少 40%-60%
+
+无需 ViewHolder、Adapter 逻辑
+
+状态与 UI 同步更新,避免 UI 状态丢失
+
+支持实时预览(@Preview)、热重载、即时调试
+
+
+我们在公司项目中构建了性能对比 Benchmark(测试设备为 Pixel 6、Android 13):
+
+2.1 滚动列表对比:RecyclerView vs LazyColumn
+
+指标 RecyclerView LazyColumn (Compose) 差异
+平均帧率
+48 fps
+58 fps
++20%
+内存占用
+28 MB
+22 MB
+-21%
+首次绘制耗时
+320 ms
+210 ms
+-34%
+
+
+2.2 原因解析:Compose 更快的秘密
+
+SlotTable:结构快照树
+Compose 编译器会将 Composable 函数转换为组装 SlotTable 的代码。SlotTable 是一种高效的数据结构,存储了 Composable 树的结构快照。当状态发生变化时,Compose 通过对比 SlotTable 的版本,精确地定位变化范围,从而进行最小代价的重组操作(recomposition)。这一过程通过 Composer 对 Slot 表的操作实现,避免了冗余 UI 节点更新。
+
+重组与 Group 管理机制
+Compose 使用 Group(startGroup/endGroup)对 Composable 调用进行打包与标识,每个重组区域会通过重新执行对应的 Group 来进行更新,确保仅变更部分被执行。此机制在 RecomposeScopeImpl 中有体现,它能追踪每个状态依赖的作用域,从而提升重组精度。
+
+无需 ViewHolder 回收
+传统 RecyclerView 需要手动管理视图缓存与回收,而 Compose 自动处理 Composition 节点生命周期。Compose Compiler 会生成高效的 Slot 操作指令,通过“skip、reuse”策略对 UI 层进行精准控制,避免重复创建与销毁。
+
+Skia 图形引擎与 RenderNode
+Compose 绘制层基于 Skia 引擎,使用 DrawModifier 直接对 Canvas 进行渲染。它不会像传统 View 那样层层嵌套测量布局与绘制流程,而是采用测量(MeasurePass)-> 布局(LayoutPass)-> 绘制(DrawPass)的管线逻辑,通过 LayoutNode 驱动 Compose UI 树的变化。同时 Compose Layout 使用 SubcomposeLayout 实现异步测量能力,提高复杂嵌套组件的性能表现。
+
+渲染流程对比
+阶段 View System Compose
+布局树管理
+View/ViewGroup 层级
+LayoutNode 节点
+渲染方式
+Choreographer + RenderThread
+FrameClock + Skia 渲染
+状态追踪
+手动触发 invalidate
+Snapshot 自动追踪 + Diff Patch
+更新路径
+requestLayout → measure/layout
+Recomposer + SlotTable 重组
+
+注意:Compose 并非所有场景都一定更快,特别是复杂嵌套、过度组合场景仍需谨慎使用。
+
+### 简介
+
+Jetpack Compose 是用于构建 Android 界面的新款工具包。
+
+
+Jetpack Compose 是用于构建原生 Android 界面的新工具包。它使用更少的代码、强大的工具和直观的 Kotlin API,可以帮助您简化并加快 Android 界面开发,打造生动而精彩的应用。它可让您更快速、更轻松地构建 Android 界面。
+
+
+编写更少的代码会影响到所有开发阶段:作为代码撰写者,需要测试和调试的代码会更少,出现 bug 的可能性也更小,您就可以专注于解决手头的问题;作为审核人员或维护人员,您需要阅读、理解、审核和维护的代码就更少。
+
+与使用 Android View 系统(按钮、列表或动画)相比,Compose 可让您使用更少的代码实现更多的功能。无论您需要构建什么内容,现在需要编写的代码都更少了。以下是我们的一些合作伙伴的感想:
+
+“对于相同的 Button 类,代码的体量要小 10 倍。”(Twitter)
+“使用 RecyclerView 构建的任何屏幕(我们的大部分屏幕都使用它构建)的大小也显著减小。”(Monzo)
+““只需要很少几行代码就可以在应用中创建列表或动画,这一点令我们非常满意。对于每项功能,我们编写的代码行更少了,这让我们能够将更多精力放在为客户提供价值上。”(Cuvva)
+编写代码只需要采用 Kotlin,而不必拆分成 Kotlin 和 XML 部分:“当所有代码都使用同一种语言编写并且通常位于同一文件中(而不是在 Kotlin 和 XML 语言之间来回切换)时,跟踪变得更容易”(Monzo)
+
+无论您要构建什么,使用 Compose 编写的代码都很简洁且易于维护。“Compose 的布局系统在概念上更简单,因此可以更轻松地推断。查看复杂组件的代码也更轻松。”(Square)
+
+
+
+Compose 使用声明性 API,这意味着您只需描述界面,Compose 会负责完成其余工作。这类 API 十分直观 - 易于探索和使用:“我们的主题层更加直观,也更加清晰。我们能够在单个 Kotlin 文件中完成之前需要在多个 XML 文件中完成的任务,这些 XML 文件负责通过多个分层主题叠加层定义和分配属性。”(Twitter)
+
+
+Compose 与您所有的现有代码兼容:您可以从 View 调用 Compose 代码,也可以从 Compose 调用 View。大多数常用库(如 Navigation、ViewModel 和 Kotlin 协程)都适用于 Compose,因此您可以随时随地开始采用。“我们集成 Compose 的初衷是实现互操作性,我们发现这件事情已经‘水到渠成’。我们不必考虑浅色模式和深色模式等问题,整个体验无比顺畅。”(Cuvva)
+
+
+为现有应用设置 Compose
+
+首先,使用 Compose Compiler Gradle 插件配置 Compose 编译器。
+
+然后,将以下定义添加到应用的 build.gradle 文件中:
+```
+android {
+ buildFeatures {
+ compose = true
+ }
+}
+```
+在 Android BuildFeatures 代码块内将 compose 标志设置为 true 会在 Android Studio 中启用 Compose 功能。
+
+
+Compose vs HarmonyOS ArkUI 对比分析
+
+
+Jetpack Compose 和 HarmonyOS ArkUI 均采用声明式 UI 编程范式,面向多设备场景的响应式 UI 构建,二者在理念相通的同时,在架构设计、状态模型、渲染机制等方面有显著区别。
+
+
+
+
+
+Jetpack Compose 是围绕可组合函数构建的。这些函数可让您以程序化方式定义应用的界面,只需描述应用界面的外观并提供数据依赖项,而不必关注界面的构建过程(初始化元素、将其附加到父项等)。如需创建可组合函数,只需将 @Composable 注解添加到函数名称中即可。
+
+
+
+---
+
+- 邮箱 :charon.chui@gmail.com
+- Good Luck!
\ No newline at end of file
diff --git "a/AdavancedPart/ConstraintLaayout\347\256\200\344\273\213.md" "b/AdavancedPart/ConstraintLaayout\347\256\200\344\273\213.md"
index f46d2dc2..e3ccc9fc 100644
--- "a/AdavancedPart/ConstraintLaayout\347\256\200\344\273\213.md"
+++ "b/AdavancedPart/ConstraintLaayout\347\256\200\344\273\213.md"
@@ -12,8 +12,6 @@ ConstraintLaayout简介
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
```
-
-
然后会提示添加`ConstraintLayout`支持库。
@@ -95,7 +93,7 @@ implementation 'com.android.support.constraint:constraint-layout:1.1.0'
* layout_constraintVertical_bias
```
- 下面这段代码就是让左边占30%,右边占70%(默认两边各占50%),这样左边就会短一些,如图5所示,此时代码是这样的:
+ 下面这段代码就是让左边占30%,右边占70%(默认两边各占50%),这样左边就会短一些,此时代码是这样的:
```xml