自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

tmacfrank

分享移动开发领域知识

  • 博客(139)
  • 收藏
  • 关注

原创 Android 性能优化入门(三)—— ANR 问题分析

本文系统介绍了Android应用性能优化中的ANR问题,包括ANR概念、4种类型(Input事件、广播、服务和ContentProvider超时)及产生原因(如主线程IO操作、死锁等)。重点讲解了ANR问题的线下分析方法,包括3种关键日志文件的使用和线程状态分析技巧,并提供了两种线上监控方案:FileObserver监听/data/anr目录变化和WatchDog机制。文章还特别强调了面试时应先讲整体分析思路再展开细节的应对策略。

2025-05-25 23:57:18 465

原创 TCP/IP 协议族

本文介绍了计算机网络体系结构,重点分析了OSI参考模型和TCP/IP模型的分层设计。文章首先阐述了7层OSI模型和4层TCP/IP模型的对应关系,解释了分层的主要目的是应对网络不稳定性,通过分块传输降低重传成本。随后详细说明了TCP/IP协议族的分层工作原理,包括各层如何添加首部信息、处理数据包以及实现可靠传输。文章强调分层架构实现了功能解耦,使不同协议能共享传输机制,每层只需关注自身功能实现,共同构成了互联网的基础通信架构。

2025-05-25 23:53:19 524

原创 Android 网络全栈攻略(五)—— 从 OkHttp 拦截器来看 HTTP 协议二

本文继续解析OkHttp剩余的四个拦截器,重点介绍桥接拦截器(BridgeInterceptor)。该拦截器位于请求准备和实际发送之间,自动处理HTTP协议细节,如设置请求头、处理Cookie、gzip压缩等。其核心逻辑分为三步:1)前置工作补充必要请求头;2)中置工作触发下一个拦截器;3)后置工作处理响应数据(如gzip解压)。特别处理了Content-Length与Transfer-Encoding的互斥关系,简化了开发者处理HTTP协议的工作量。

2025-05-23 23:51:45 202

原创 Android 网络全栈攻略(四)—— 从 OkHttp 拦截器来看 HTTP 协议一

上一篇我们详解了 OkHttp 的众多配置,本篇来看 OkHttp 是如何通过责任链上的内置拦截器完成 HTTP 请求与响应的,目的是更好地深入理解 HTTP 协议。这仍然是一篇偏向于协议实现向的文章,重点在于 HTTP 协议的实现方法与细节,关于责任链模式这些设计模式相关的内容,由于与 HTTP 协议关联不大,因此只是有所提及但不会着重讲解。

2025-05-23 23:04:23 1116 2

原创 Android 网络全栈攻略(三)—— 从三方库原理来看 HTTP

前面两篇文章我们介绍了 HTTP 协议的请求方法、请求码以及常用的请求头/响应头的知识。本篇会从 OkHttp 配置的角度来看这些框架是如何实现 HTTP 协议的,目的是加深对 HTTP 的理解,并学习协议是如何落地的。我们会选取 OkHttp 中与协议实现相关的源码作为切入点,而不是去全面地分析这两个框架的源码。

2025-05-22 23:40:22 1632

原创 Android 网络全栈攻略(二)—— 登录与授权

身份认证本质:确认"你是你"的过程,通过用户名密码验证建立屏幕前用户与账户所有者的关联验证流程:用户输入凭证→服务器验证→确认身份→赋予账户权限权限特点:登录后获得的权限是直接赋予用户自身,不涉及第三方令牌核心概念:将特定权限通过象征性令牌授予第三方令牌形式:可以是授权文件、授权码(token)等数字凭证经典案例:尚方宝剑比喻皇上(授权方)→包青天(持有方)→尚方宝剑(令牌)实现效果:持有令牌者可执行超出原有权限的操作(如斩杀高官)

2025-05-19 23:38:21 821

原创 Android 网络全栈攻略(一)—— HTTP 协议基础

本文介绍了HTTP协议的基本原理与工作机制、请求方法与状态码、以及Header与Body的结构。HTTP(超文本传输协议)最初用于传输HTML文档,通过URL定位资源,基本工作流程包括客户端发送请求、服务器处理并返回响应。请求报文由请求行、请求头和请求体组成,响应报文包含状态码和响应体。常用的请求方法包括GET、POST、PUT、DELETE和HEAD,状态码分为1xx(临时消息)、2xx(成功)、3xx(重定向)、4xx(客户端错误)和5xx(服务器错误)。Header用于描述核心数据的属性,如Host和

2025-05-19 23:20:37 1341 1

原创 Android 性能优化入门(二)—— 内存优化

首先,在 LeakCanary 的部分模块的 AndroidManifest.xml 中会声明一些 Provider,这些 Provider 在 apk 打包时会汇入 mergeAndroidManifest.xml,最后体现在 app 的 AndroidManifest.xml 文件中。A~G 每个对象都占 10 个内存单位,它们的浅堆都是 10,但是 B、C 的深堆就要计算上各自分支上的对象总和,即 30,而 A 要计算分支上所有对象的内存总和,即 70。

2025-05-18 23:53:59 1381

原创 Android 性能优化入门(一)—— 数据结构优化

一款 app 除了要有令人惊叹的功能和令人发指交互之外,在性能上也应该追求丝滑的要求,这样才能更好地提高用户体验,响应速度一项就主要取决于数据结构和算法。

2025-05-18 23:49:59 1243

原创 网络编程中的直接内存与零拷贝

本篇文章会介绍 JDK 与 Linux 网络编程中的直接内存与零拷贝的相关知识,最后还会介绍一下 Linux 系统与 JDK 对网络通信的实现。

2025-05-17 23:50:28 978

原创 Java 原生网络编程(BIO | NIO | Reactor 模式)

Java 原生网络编程 BIO、NIO

2025-05-17 23:42:50 1195

原创 Java 并发编程归纳总结(可重入锁 | JMM | synchronized 实现原理)

可重入锁、Java 内存模型 JMM、synchronized 关键字实现原理

2025-05-16 23:54:29 1072

原创 AQS 基本思想与源码分析

充分了解 AbstractQueuedSynchronizer 对于深入理解并发编程是有益处的,它是用来构建锁或者其他同步组件的基础框架,我们常用的同步工具类如 CountDownLatch、Semaphore、ThreadPoolExecutor、ReentrantLock 和 ReentrantReadWriteLock 内部都用到了它。

2025-05-16 23:48:40 815

原创 Compose 实践与探索十七 —— 多指手势与自定义触摸反馈

前面我们讲了很多半自动化 API 进行手势识别,那些 API 可以覆盖绝大多数的使用场景。本节我们来介绍,如何通过底层 API 实现完全自定义的触摸算法。

2025-03-28 16:43:52 1020

原创 Compose 实践与探索十一 —— ParentDataModifier

)但是这样的话,在实现 modifyParentData() 的具体内容时,你需要去查阅 Box 的父组件 Row 的内部都用到了哪些 parentData,这是一件很麻烦的事情。因此,这种方式不可行。@Stable。

2025-03-25 16:08:13 1260

原创 Kotlin 协程官方文档知识汇总(一)

Kotlin 是一门仅在标准库中提供最基本底层 API 以便其他库能够利用协程的语言。与许多其他具有类似功能的语言不同,async与await在 Kotlin 中并不是关键字,甚至都不是标准库的一部分。此外,Kotlin 的挂起函数概念为异步操作提供了比 future 与 promise 更安全、更不易出错的抽象。kotlinx.coroutines 是由 JetBrains 开发的功能丰富的协程库。使用协程需要添加对 kotlinx-coroutines-core 模块的依赖,如。

2025-03-22 23:53:56 1217

原创 Compose 实践与探索十九 —— Compose 显示原理浅析

Compose 的组件都是放在 setContent() 之后才能显示的,那需要先看看这个函数的作用。先看 ComponentActivity 的扩展函数 setContent():setContent() 的主要任务是将用户写的 Compose 组件设置为 Activity 的显示内容。具体说来,就是将 Compose 组件封装进 ComposeView 中,然后用 ComponentActivity 的 setContentView() 设置当前 Activity 显示这个 ComposeView。在

2025-03-22 23:47:19 687

原创 Compose 实践与探索十八 —— Compose 与 View 混用

Compose 发展初期的几年,会是新的模块用 Compose 写,然后逐渐的把老界面从 View 替换成 Compose 组件,直到全部或几乎全部是 Compose 代码的模式。原生的 SurfaceView 与 TextureView 的重点是在它们底层的 Surface API,而不是 View 本身。Compose 并没有给出对等的实现,因此倘若你的项目中用到了它们,就仍需继续使用它们。这也是 View 到 Compose 的迁移到“几乎全部是 Compose 代码”的原因。

2025-03-21 23:11:19 501

原创 Compose 实践与探索十六 ——滑动检测与嵌套滑动

这里对以上内容就不再赘述了,直接去讲解更复杂的 Modifier 实现更复杂的触摸反馈效果。在传统的 View 体系中,在自定义触摸反馈的内容时,对于 View 我们通常都是重写它的 onTouchEvent(),对于 ViewGroup 可能还需要重写 onInterceptTouchEvent(),极少数时候会更深入地去重写 dispatchTouchEvent()。

2025-03-21 23:09:47 1082

原创 Compose 实践与探索十五 —— 自定义布局

自定义布局在 Compose 中相对于原生的需求已经小了很多,先讲二者在本质上的逻辑,再说它们的使用场景,两相对比就知道为什么 Compose 中的自定义布局的需求较小了。原生是在 xml 布局文件不太方便或者无法满足需求时才会在代码中通过自定义 View 的方式,重写 onMeasure() 或 onLayout(),或添加其他功能方法来实现需求。

2025-03-17 23:23:30 1264

原创 Compose 实践与探索十四 —— 自定义绘制

不论是在传统的 View 体系下,还是在 Compose 中,“自定义 View” 都包含视图的测量、布局、绘制、触摸反馈以及动画。说到 Compose 的自定义绘制,Compose 提供了更加上层的 API,相比于原生的绘制 API 会更简单、更直接一些。比如原生的 Canvas 和 Paint 在 Compose 中进行正常绘制时是用不到的,只有在使用原生独有的绘制功能(比如多维旋转)时才需要下沉到原生这一层去使用它们。

2025-03-17 23:22:02 1493

原创 Compose 实践与探索十三 —— 附带效应

Google 官方文档对 side effect 有两种翻译,简体中文翻译为附带效应,繁体中文翻译为副作用。本篇文章将全面介绍 Compose 的附带效应 API 的用法以及原理,帮助你区分不同 API 的使用场景。

2025-03-16 22:42:47 819

原创 Compose 实践与探索十二 —— 其他 Modifier

addBeforeLayoutModifier() 与 addAfterLayoutModifier() 并不是指在 Modifier 链上先处理哪个或者后处理哪个具体的 Modifier,而是指同一个 Modifier 具有多重“身份”时,先/后处理哪个“身份”。

2025-03-16 22:40:44 629

原创 Compose 实践与探索十 —— PointerInputModifier 与 SemanticsModifier

作用:ParentDataModifier 用于给子组件附加一些属性,让父组件可以利用用法:只有在通过 Layout() 写自定义函数时才会用到 ParentDataModifier,在测量与布局的算法中通过 Measurable 的 parentData 属性拿到这个数据后根据具体需求使用即可,最后要提供一个 Modifier 函数实现 ParentDataModifier,在 modifyParentData() 中根据需求提供附加数据。

2025-03-15 23:04:30 762

原创 Compose 实践与探索九 —— DrawModifier 解析

每个 LayoutNodeWrapper 中的 entities 数组中的 DrawModifier 是伪造的,要不写在 Box() 的示例代码中会很占篇幅。LayoutNode 的 draw() 调用 outerLayoutNodeWrapper,也就是 LayoutNodeWrapper,在上面的层级图中的 ModifiedLayoutNode1 的 draw() 开始绘制。

2025-03-15 23:02:22 894

原创 Compose 实践与探索八 —— LayoutModifier 解析

前面几节讲的 Modifier 都是起辅助作用的,比如 Modifier 的伴生对象、CombinedModifier、 ComposedModifier 以及几乎所有 Modifier 的父接口 Modifier.Element。本篇我们开始讲具有直接功效的 Modifier,分为几个大类:LayoutModifier、DrawModifier 等。

2025-03-14 22:38:19 1123

原创 Compose 实践与探索七 —— Modifier 基础

从本篇文章开始我们要讲解 Modifier 修饰符,它是一个很精妙的东西,允许我们通过链式调用的方式为组件应用一系列的样式设置,如边距、字体、位移等。在 Compose 中,每个基础的 Composable 组件都有一个 modifier 参数,通过传入自定义的 Modifier 修改组件的样式。此外,前面我们还提过 Modifier 调用链对顺序敏感,不同的调用顺序会产生不同的 Modifier 链从而影响最终的 UI 效果,这是 Compose 按照 Modifier 链来顺序完成页面布局与绘制的结

2025-03-14 22:35:32 914

原创 Compose 实践与探索六 —— Transition 及其关联 API

本篇是动画的最后一篇,我们先介绍 Transition API,然后再介绍与 Transition 相关的三个上层 API:AnimatedVisibility()、Crossfade()、AnimatedContent()。

2025-03-13 23:29:16 1010

原创 Compose 实践与探索五 —— 动画进阶

介绍 Compose 动画的各种 AnimationSpec。

2025-03-13 23:23:43 829

原创 Compose 实践与探索四 —— 单值动画

现在在 Android 开发领域说的动画几乎就是属性动画。这节以 animateDpAsState() 为代表,介绍 animateXxxAsState() 这一系列函数。animateDpAsState() 已经包含了 mutableStateOf() 这种数据改变通知监听者的功能,同时还包含 remember() 防止多次初始化的功能,因此创建动画属性就不用 remember() 和 mutableStateOf() 了。

2025-03-11 03:23:38 1502

原创 Compose 实践与探索三 —— 深入理解重组

CompositionLocal 按照字面意思可直译为 Composition 的局部变量。User(name)name 变量只在 setContent() 后的代码块内有效,并且不能穿透到代码块调用的 User 函数之内。User()// 这里会报错的,User 函数的内部访问不到 name 变量Text(name)Compose 提供的 CompositionLocal 可以帮助我们突破这个限制,让通过 CompositionLocal 创建的局部变量具备穿透函数的能力。

2025-03-11 03:20:29 679

原创 Compose 实践与探索二 —— 状态订阅与自动更新

Compose 官方称其是无状态的(Stateless),这个状态是指组件属性。比如说 TextView 内保存的文字内容就是一个状态,你可以通过 getText() 与 setText() 获取与设置文字。但在 Compose 中,组件没有状态,也就是其内部不会保存这些数据,在将数据设置到 UI 上之后,它们就被“扔掉了”。但需要注意的是,无状态作为 Compose 的一个特点,它是允许组件无状态,而不是说组件绝对没有状态。

2025-03-10 22:45:36 1301

原创 Compose 实践与探索一 —— 关键知识与概念详解

本节主要概括性地介绍 Jetpack Compose 中的关键概念。

2025-03-10 22:41:40 952

原创 Compose 的集成与导航

首先我们来看如何在 View 体系中集成 Compose。

2025-01-13 23:59:45 1324

原创 Kotlin 协程基础十 —— 协作、互斥锁与共享变量

本节将介绍在协程间如果有先后执行、互相等待的需求时,应该怎样去处理这种等待和协作的工作。更会与 Java 的线程的协作工作对比,从而说明,在线程中通常不太简单的协作操作,在协程中很容易实现。

2025-01-12 23:49:17 1219 1

原创 Kotlin 协程基础九 —— SharedFlow 与 StateFlow

SharedFlow 与 StateFlow 是 Flow 的两个变种,它们把 Flow 的功能从数据流的收集改成了事件流和状态的订阅,这就把适用场景切换到了一个非常实用的范围。

2025-01-12 23:48:43 1433

原创 Kotlin 协程基础八 —— Flow 操作符(二)

本篇是 Flow 操作符的第二篇文章,会讲解异常相关操作符、流程监听操作符、flowOn、buffer 操作符、Flow 合并操作符以及将 Flow 转换为其他类型的操作符。

2025-01-12 23:47:51 742

原创 Kotlin 协程基础七 —— Flow 操作符(一)

Flow 的操作符指的是用一个或多个 Flow 对象,来创建出另一个新的 Flow 对象的函数。接下来我们会用两篇的篇幅来介绍 Flow 的常用操作符。

2025-01-12 23:47:17 1175

原创 Kotlin 协程基础六 —— Flow

上一篇我们讲解了 Channel 的相关知识。Channel 是一个跨协程传递数据的工具,属于底层工具,不是拿来直接用的,尤其是在近些年 Flow API 被推出并逐渐完善之后,Channel 都不太适合当做一个上层的功能性工具来用了。如果需要事件流或数据流,还是用 Flow 比较好。Channel 现在更多是作为 Flow API 的一个关键的底层支撑而存在,它给 Flow 提供了跨协程的能力。从功能上说,Flow 更完整,使用体验更顺畅。本篇我们就开始了解 Flow 的相关内容。

2025-01-12 23:46:22 1021

原创 Kotlin 协程基础五 —— Channel

前面我们讲解的 Channel 的相关知识。Channel 是一个跨协程传递数据的工具,属于底层工具,不是拿来直接用的,尤其是在近些年 Flow API 被推出以及逐渐完善之后,Channel 都不太适合当做一个上层的功能性工具来用了。如果需要事件流或数据流,还是用 Flow 比较好。Channel 现在更多是作为 Flow API 的一个关键的底层支撑而存在,它给 Flow 提供了跨协程的能力。从功能上说,Flow 更完整,使用体验更顺畅。这一篇我们就开始了解 Flow 的相关内容。

2025-01-12 23:42:41 991

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除