自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(141)
  • 收藏
  • 关注

原创 反思: Google 为何把 SurfaceView 设计的这么难用?

如果你有过SurfaceView的使用经历,那么你一定和我一样,曾经被它所引发出层出不穷的异状折磨的怀疑人生—— 毕竟,作为一个有理想的开发者,在深入了解 SurfaceView之前,你很难想通这样一个问题: 为什么 Google 把 SurfaceView 设计的这么难用?

2022-09-06 17:13:22 14217 8

原创 反思 | 事件总线的局限性,组件化开发流程中通信机制的设计与实现

反思 系列博客是我的一种新学习方式的尝试,该系列起源和目录请参考 这里 。背景诸如EventBus\RxBus\LiveDataBus的事件总线库在业内正遭滥用。诚然,事件总线看起来 小而美 ,但随着业务复杂度上升,事件的发送和订阅到处分布,这个优势反而成为了负担,因此,笔者不建议在任何量级的项目中使用事件总线库。更多原因读者可参考 这篇文章 。更合理的方案是什么呢?在量级较小的项目中,开发者应该通过 依赖注入 将Callback进行不同层级的依次传递,以保证 层级间的依赖关系足够清晰。而对于.

2021-01-16 20:35:05 11713 12

原创 反思|官方也无力回天?Android SharedPreferences的设计与实现

反思|官方也无力回天?Android SharedPreferences的设计与实现反思 系列博客是我的一种新学习方式的尝试,该系列起源和目录请参考 这里 。起源就在前几日,有幸拜读到 HiDhl 的文章,继腾讯开源类似功能的MMKV之后,Google官方维护的 Jetpack DataStore 组件横空出世——这是否意味着无论是腾讯三方还是Google官方的角度,SharedPreferences都彻底告别了这个时代?无论是MMKV的支持者还是DataStore的拥趸,SharedPrefe

2020-10-17 16:36:37 8536 5

原创 反思|Android 事件拦截机制的设计与实现

「反思」 系列是笔者一个新的尝试,其起源与目录请参考 这里 。概述完整的掌握 Android 事件分发体系并非易事,其整个流程涉及到了 系统启动流程(SystemServer)、输入管理(InputManager)、系统服务和UI的通信(ViewRootImpl + Window + WindowManagerService)、View层级的 事件分发机制 等等一系列的环节。事件拦截机制...

2020-04-15 23:37:00 1778 1

原创 中秋节听夜曲,Android OpenGL 呈现周董专属的玉兔主题音乐播放器

前几天发现QQ音乐有个好玩的功能,为用户提供了多种播放器主题,其中原神的主题让我眼前一亮:当然,诸如换肤、主题类的功能已经屡见不鲜,但这类沉浸式播放器的听歌体验确实不错。见猎心喜,正好中秋马上就到,我也尝试整个中秋主题音乐播放器试试水。整体思路有2点:首先是技术方面,纯粹的ImageView图层堆砌来实现,渲染效率太低OpenGL是一个不错的技术方案(QQ应该也是这么实现的),顺便复习下图形学的知识。其次是玩法上,干脆在基础的功能上加一些更好玩的。

2023-09-21 23:34:52 683

原创 Android 音频可视化:频谱特效的探索与实践

经过以上几步处理,单帧效果得到明显改善,但随着划入时间维度之后,相邻两帧的展示效果有明显的跳跃性,对于用户而言就好像掉帧一样。这里我们引入衰减系数,每一帧数据绘制前,与上一帧数据进行对比,当单个频率点数据发生较高的抖动,通过衰减系数对抖动进行抑制。

2023-07-12 18:20:50 3027 1

原创 反思|浅谈 WorkManager 的设计与实现:系统概述

本文笔者将通过针对 `Android` 的后台任务管理机制,进行一个系统性的分析和设计。

2023-07-05 13:40:45 571

原创 Unity3D-在Android平台快速验证功能的更新

Unity平台能够提供非常强大的2D、3D特效,相比OpenGL而言,使用Unity` 意味着更低的开发成本,更便捷的可视化开发体验。在常规的 Unity 开发中,与 Android 的联调通常使用 建立Unity项目 - 导出Android项目 - 编写并导出aar - 导入Unity再次编辑 - 再次导出apk 来实现,整体过于繁琐,无法满足在双平台的开发过程中,频繁修改、联调 的需求。本文将针对两个平台如何快速验证功能的更新,进行简单的分析。1. 实现步骤 & 验证先说结论 :Unit

2022-04-30 15:40:56 2650

原创 Unity3D-消息机制实现与Android的通信

Unity 平台能够提供非常强大的 2D、3D 特效,相比 OpenGL 而言,使用 Unity 意味着更低的开发成本,更便捷的可视化开发体验。本文将针对 Unity 和 Android 平台之间,如何进行双向通信进行总结。1. Unity项目搭建首先创建一个简单的项目,创建一个 Canvas,并放一个简单的 Text 文字控件:接下来编写一个简单的脚本,并将脚本绑定到 Canvas 上:using System;using System.Collections;using System.C

2022-04-29 22:38:59 3261

原创 Unity3D-导出特效到安卓项目流程

本文将针对将 Unity 的项目导出到 Android 平台的步骤进行一个总结。首先点击File-Building Settings,打开配置面板:打开面板后,切换Android栏,准备导出项目,如果是第一次导出,那么Unity没有找到对应的开发环境配置,提示需要下载,以iOS为例:在 Unity Hub 上,需要手动指定下载的依赖,包括Android SDK 和 NDK, 下载安装完成后,需重启Unity,再回到配置面板,此时已经可用了:主面板提供了一些基础的配置,其中最重要的是Export

2022-04-22 17:14:34 5691

原创 Android OpenGL 仿自如 APP 裸眼 3D 效果

概述之前看到 自如团队 发布的 自如客APP裸眼3D效果的实现 ,非常有趣,不久后,社区内 Android 的开发者们陆续提供了 Flutter、 Android 原生 、Android Jetpack Compose 等不同的实现版本。很快我看到了一个好玩的评论:既然客户端都卷成这样了,干脆破罐破摔,把 Android OpenGL 的实现版本也补齐,毕竟 图形学或许会迟到,但绝不会缺席 。实现效果如下(图片来源),这一波属实参与到社区内裸眼3D的 客户端大满贯 了 :原理简介 & O

2021-11-28 23:42:01 5477

原创 Android 分场景集成不同音频倍速算法的实现

概述上文 《Android 音频倍速的原理与算法分析》 中, 我们针对音频倍速的基本原理进行了梳理,并逐步引申出了 Android 平台上常用的2种算法实现:Sonic 和 SoundTouch。初步结论是,在用户启用音频倍速时,我们需要 根据具体场景切换不同实现 ,以此保证最佳的用户体验。举例来说,对于常规音乐——尤其是背景乐、打击感比较强的音乐,我们优先选择 SoundTouch, 而对于人声更纯粹的音频(相声评书、歌手清唱等)而言,Sonic 才是更好的选择。本文以 Google 开源的 E

2021-11-13 23:42:54 3720 1

原创 Android 音频倍速的原理与算法分析

概述音视频倍速 是内容类APP非常重要的功能,其内部包含了 视频流 和 音频流 的倍速,其中视频倍速原理相对简单,即在解码视频帧时提升帧率即可。音频倍速 相对复杂,众所周知,声音的本质其实是 物体振动时产生的声波,因此音频的倍速是 将语音信号在时域上拉长或缩短,考虑到用户的体验,在保证声音变速的同时,语音的采样率、基频以及共振峰都不能发生变化,以此达到 变速不变调 的目的。对于 Android 平台的应用而言,音频倍速通常有3种实现方式:实现方案应用简介Android Audi

2021-10-31 00:58:20 6304 2

原创 反思 | Android 音视频缓存机制的系统性设计

反思 系列博客是我的一种新学习方式的尝试,该系列起源和目录请参考 这里 。背景在自媒体的时代,音视频播放 俨然已成为内容类型 APP 最基础的能力,对于 Android 开发者而言,无论是 Google 开源的 ExoPlayer ,还是 Bilibili 开源的 ijkplayer , 都是构建应用音视频播放能力时优秀的选择。虽然上述的三方播放器都自带完善的缓存功能,但对于内容和形式都日新月异的一众互联网产品来说,想要打造完美契合自家产品的用户体验,播放器自身的缓存机制已逐渐无法满足需求。最具.

2021-09-25 22:47:47 801

翻译 [译] Android Visualizer 可视化器的自定义实现

原文:An alternative Android Visualizer作者:Dániel Zolnai译者:却把清梅嗅听音乐时,有时你会看到那些视觉上令人愉悦的跃动条,它们音量越大跳得越高。通常,左边的条形对应的频率较低(低音),而右边的条形对应较高的频率(高音):这些跃动条通常被称为 视觉均衡器 或 可视化器,若想在 Android 应用中展示类似的可视化效果,你可以使用 Android 原生的 Visualizer 类,它是Android框架中的一部分,且能够附加到你的 AudioTra.

2021-08-14 08:36:14 2108

原创 反思|开启B站少女心模式,探究APP换肤机制的设计与实现

反思 系列博客是我的一种新学习方式的尝试,该系列起源和目录请参考 这里 。概述换肤功能 并非奇技淫巧,而是已非常普及,尤其当Android Q推出了 深色模式 之后,国内绝大多数主流应用都至少提供了 日间 和 夜间 两种模式。对于无感的用户而言,这个功能实属鸡肋,但从另外一个角度上来说,这也是产品在雕琢 用户极致体验 过程中的一次尝试,为不同情景下,不同偏好的用户提供更多的选择性。以 哔哩哔哩 为例,除了提供以上两种主题之外,还免费提供了充满 少女心 的粉色主题:从产品的前瞻性上来看,国内在.

2021-05-22 15:27:56 9487 14

原创 每日一题 | 曾被反转链表支配的恐惧

前段时间看到掘金平台推出了每日算法打卡的活动,感觉挺好,好巧不巧打开LeetCode的每日一题刚好是 反转链表,这道去年年初面试字节跳动挂掉的算法题,趁这个机会把之前算法的记忆捡回来。Date: 2021-03-21 Week121、反转链表 II难度:Medium题目描述给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。..

2021-03-21 22:27:36 509

翻译 [译] 编写AndroidStudio插件(五):本地化和通知

原文:Write an Android Studio Plugin Part 5: Localization and Notifications作者:Marcos Holgado译者:却把清梅嗅《编写AndroidStudio插件》系列是 IntelliJ IDEA 官方推荐的学习IDE插件开发的博客专栏,希望对有需要的读者有所帮助。在本系列的第四部分中,我们学习了如何在插件中集成诸如Jira Cloud Platform之类的第三方API,以及如何使用MVP或MVC之类的模式开发。本文我将部分.

2021-01-25 17:36:37 1257 1

翻译 [译] 编写AndroidStudio插件(四):集成Jira

原文:Write an Android Studio Plugin Part 4: Jira Integration作者:Marcos Holgado译者:却把清梅嗅《编写AndroidStudio插件》系列是 IntelliJ IDEA 官方推荐的学习IDE插件开发的博客专栏,希望对有需要的读者有所帮助。在本系列的第三部分中,我们学习了如何使用Component对数据进行持久化,并利用这些数据来创建新的设置页面。在今天的文章中,我们将使用这些数据将Jira与我们的插件快速集成在一起。请记住.

2021-01-24 14:48:30 1678

翻译 [译] 编写AndroidStudio插件(三):设置页

原文:Write an Android Studio Plugin Part 3: Settings作者:Marcos Holgado译者:却把清梅嗅《编写AndroidStudio插件》系列是 IntelliJ IDEA 官方推荐的学习IDE插件开发的博客专栏,希望对有需要的读者有所帮助。在本系列的第二部分中,我们学习了如何使用Component对数据进行持久化,以及通过这些数据,在用户更新我们的插件后展示更新了哪些新功能。在今天的文章中,我们将看到如何使用持久化的数据来创建设置页面。请记.

2021-01-23 22:20:33 1366

翻译 [译] 编写AndroidStudio插件(二):持久化数据

原文:Write an Android Studio Plugin Part 2: Persisting data作者:Marcos Holgado译者:却把清梅嗅《编写AndroidStudio插件》系列是 IntelliJ IDEA 官方推荐的学习IDE插件开发的博客专栏,希望对有需要的读者有所帮助。在本系列的第一部分中,我们了解了如何为Android Studio创建一个基本的插件,并编写了第一个Action。本文我们将了解如何在插件中对数据进行持久化。请记住,您可以在GitHub上找.

2021-01-22 17:53:25 2495 1

翻译 [译] 编写AndroidStudio插件(一):创建一个基本插件

原文:Write an Android Studio Plugin Part 1: Creating a basic plugin作者:Marcos Holgado译者:却把清梅嗅《编写AndroidStudio插件》系列是 IntelliJ IDEA 官方推荐的学习插件IDE开发博客专栏,希望对有需要的读者有所帮助。早在10月的时候,我就在Droidcon UK 2018上针对如何在Android Studio上创建自己的插件,以及如何使所有相关操作自动化进行了讨论。因为当时我并没有很多时间对.

2021-01-21 20:38:55 4047 2

原创 反思|Android 输入系统 & ANR机制的设计与实现

反思 系列博客是我的一种新学习方式的尝试,该系列起源和目录请参考 这里 。概述对于Android开发者而言,ANR是一个老生常谈的问题,站在面试者的角度,似乎说出 「不要在主线程做耗时操作」 就算合格了。但是,ANR机制到底是什么,其背后的原理究竟如何,为什么要设计出这样的机制?这些问题时时刻刻会萦绕脑海,而想搞清楚这些,就不得不提到Android自身的 输入系统 (Input System)。Android自身的 输入系统 又是什么?一言以蔽之,任何与Android设备的交互——我们称之为 输.

2020-08-24 22:14:25 2477

原创 反思|Android源码模块化管理工具Repo分析

「反思」 系列是笔者对于 学习归纳 一种新的尝试,其起源与目录请参考 这里 。起源随着Android项目 模块化 或 插件化 项目业务的愈发复杂,开发流程中通过版本控制工具(比如Git)管理项目的成本越来越高。以大名鼎鼎的 Android源代码开源项目 (Android Open-Source Project,下文简称 ASOP)为例,截止2020年初,Android10的源码项目,其模...

2020-05-05 16:10:17 1758

原创 哈希映射用法及算法例题

本文为博主算法学习过程中的学习笔记,主要内容来源于其他平台或书籍,出处请参考下方 参考&感谢 一节。用法哈希映射 是用于存储 (key, value) 键值对的一种实现。使用哈希映射的第一个场景是,我们 需要更多的信息,而不仅仅是键。然后通过哈希映射 建立密钥与信息之间的映射关系。另一个常见的场景是 按键聚合所有信息。我们也可以使用哈希映射来实现这一目标。例题1、两数之和...

2020-03-09 01:06:01 7830 2

原创 哈希集合用法及算法例题

本文为博主算法学习过程中的学习笔记,主要内容来源于其他平台或书籍,出处请参考下方 参考&感谢 一节。用法哈希集 是集合的实现之一,它是一种存储 不重复值 的数据结构。因此,通常,使用哈希集来检查该值是否已经出现过。让我们来看一个例子:给定一个整数数组,查找数组是否包含任何重复项。这是一个典型的问题,可以通过哈希集来解决。你可以简单地迭代每个值并将值插入集合中。 如果...

2020-03-09 01:05:19 2394

原创 哈希表原理及简单设计

本文为博主算法学习过程中的学习笔记,主要内容来源于其他平台或书籍,出处请参考下方 参考&感谢 一节。介绍哈希表 是一种使用哈希函数组织数据,以支持快速插入和搜索的数据结构。有两种不同类型的哈希表:哈希集合 和 哈希映射。哈希集合是 集合 数据结构的实现之一,用于存储 非重复值。哈希映射是 映射 数据结构的实现之一,用于存储(key, value)键值对。通过选择合适的...

2020-03-09 01:04:44 1528

原创 运用递归解决二叉树相关问题

在之前的章节中,我们已经介绍了如何解决树的遍历问题。我们也已经尝试过使用递归解决树的为 前序遍历 、 中序遍历 和 后序遍历 问题。事实上,递归 是解决树相关问题的最有效和最常用的方法之一。本节中,我们将会介绍两种典型的递归方法。解决方案本小节内容节选自 LeetCode:运用递归解决树的问题 .递归是解决树的相关问题最有效和最常用的方法之一。我们知道,树可以以递归的方式定义为一个...

2020-03-04 00:30:19 897

原创 二叉树的递归与迭代遍历

二叉树的递归与迭代遍历本文将针对二叉树中几种常见的遍历方法进行介绍。遍历方式前序遍历前序遍历首先访问根节点,然后遍历左子树,最后遍历右子树。中序遍历中序遍历是先遍历左子树,然后访问根节点,然后遍历右子树。后序遍历后序遍历是先遍历左子树,然后遍历右子树,最后访问树的根节点。递归实现递归实现二叉树的遍历是非常简单的,其核心就是 深度优先搜索(DFS) 算法。由于比较简单,...

2020-02-16 00:36:14 1040

原创 栈和深度优先搜索(DFS)

与 BFS 类似,深度优先搜索(DFS)是用于在树/图中遍历/搜索的另一种重要算法。也可以在更抽象的场景中使用。正如树的遍历中所提到的,我们可以用 DFS 进行 前序遍历,中序遍历 和 后序遍历。在这三个遍历顺序中有一个共同的特性:除非我们到达最深的结点,否则我们永远不会回溯。这也是 DFS 和 BFS 之间最大的区别,BFS永远不会深入探索,除非它已经在当前层级访问了所有结点。模版递归...

2020-02-13 23:00:44 7590 1

原创 栈的设计与算法例题

栈的实现栈的实现比队列容易。动态数组 足以实现堆栈结构。这里LeetCode官方提供了一个简单的实现供参考:// "static void main" must be defined in a public class.class MyStack { private List<Integer> data; // store elements...

2020-02-12 01:50:10 2153

原创 队列和广度优先搜索

广度优先搜索(BFS)的一个常见应用是找出从根结点到目标结点的最短路径。思路1. 结点的处理顺序在第一轮中,我们处理根结点。在第二轮中,我们处理根结点旁边的结点;在第三轮中,我们处理距根结点两步的结点;等等等等。与树的层序遍历类似,越是接近根结点的结点将越早地遍历。如果在第 k 轮中将结点 X 添加到队列中,则根结点与 X 之间的最短路径的长度恰好是 k。也就是说,第一次找到目标结点时...

2020-02-08 02:34:42 2468 1

原创 循环与循环双端队列

循环队列 是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为 环形缓冲器。循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。为什么使用循环队列?这里我们先对 队列 的简单实现进行简单展示,队...

2020-01-20 23:12:12 2362

原创 弗洛伊德的乌龟与兔子

弗洛伊德的乌龟与兔子Floyd 判圈算法(Floyd Cycle Detection Algorithm),又称龟兔赛跑算法(Tortoise and Hare Algorithm),是一个可以在有限状态机、迭代函数或者链表上判断是否存在环,以及判断环的起点与长度的算法。结论1、如果链表上存在环,那么在某个环上以不同速度前进的2个指针必定会在某个时刻相遇;2、根据结论1找到的相遇点可找...

2020-01-19 22:06:14 1994

原创 面向功利编程,面向Star开源? 一个开发者的2019反思总结

我是 却把清梅嗅 ,GitHub开源社区内的一个 功利 的爱好者。去年的这个时候,我同样做了一个简短的年终总结:《2018我的博客历程:你带来微笑,我有幸得到》我不是喜欢一个花时间写非技术类型文章的人,但是每年一篇年终总结于个人确实有所裨益——时隔一年再看,这篇文章段落中的一些吹嘘自己的文字,多少都让我有点尴尬。同时,我看到了过去自己一些 不成熟的想法 ,与一年后的自己的理念有所冲突,我...

2019-12-27 01:02:04 5608 6

原创 反思|Android 列表分页组件Paging的设计与实现:架构设计与原理解析

本文是Android Jetpack Paging系列的第二篇文章;强烈建议 读者将本系列作为学习Paging 阅读优先级最高的文章,如果读者对Paging还没有系统性的认识,请参考:反思|Android 列表分页组件Paging的设计与实现:系统概述前言Paging是一个非常优秀的分页组件,与其它热门的分页相关库不同的是,Paging更偏向注重服务于 业务 而非 UI 。——我们都知道...

2019-12-01 23:39:36 1343

原创 反思|Android 列表分页组件Paging的设计与实现:系统概述

本文将对Paging分页组件的设计和实现进行一个系统整体的概述,强烈建议 读者将本文作为学习Paging 阅读优先级最高的文章,所有其它的Paging中文博客阅读优先级都应该靠后。

2019-10-25 17:40:56 1994 1

原创 反思|Android 事件分发机制的设计与实现

反思 系列博客是我的一种新学习方式的尝试,该系列起源和目录请参考 这里 。概述Android体系本身非常宏大,源码中值得思考和借鉴之处众多。以整体事件分发机制为例,其整个流程涉及到了 系统启动流程(SystemServer)、输入管理(InputManager)、系统服务和UI的通信(ViewRootImpl + Window + WindowManagerService)、事件分发 等等...

2019-08-28 18:25:42 1745 1

原创 反思|Android LayoutInflater机制的设计与实现

反思 系列博客是我的一种新学习方式的尝试,该系列起源和目录请参考 这里 。概述Android体系本身非常宏大,源码中值得思考和借鉴之处众多。以LayoutInflater本身为例,其整个流程中除了调用inflate()函数 填充布局 功能之外,还涉及到了 应用启动、调用系统服务(进程间通信)、对应组件作用域内单例管理、额外功能扩展 等等一系列复杂的逻辑。本文笔者将针对LayoutInla...

2019-08-19 16:52:14 947

原创 反思|Android View机制设计与实现:布局流程

反思 系列博客是我的一种新学习方式的尝试,该系列起源和目录请参考 这里 。概述Android本身的View体系非常宏大,源码中值得思考和借鉴之处众多,以View本身的绘制流程为例,其经过measure测量、layout布局、draw绘制三个过程,最终才能够将其绘制出来并展示在用户面前。相比 测量流程 ,布局流程 相对简单很多,如果读者不了解 测量流程 ,建议阅读这篇文章:反思 | An...

2019-08-13 18:03:09 705 1

空空如也

空空如也

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

TA关注的人

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