事件的来源
我们知道,Android 系统中,控件对手势事件的处理在 View 的 onTouchEvent
方法中,Flutter 也不例外,从 io.flutter.view.FlutterView 的这个方法开始,大致流程为将事件从 Java 转 C++ 再转 Dart 进入框架的处理流程。这里简单画个图,不详细展开。
Don't Repeat Yourself
从前文知道,init
命令的执行是通过 init.py
的 Execute
方法完成实际操作。该方法主要功能为下载 Manifest 仓库,整体流程如下图所示:
Google 选择了 Git 作为 AOSP 的版本控制系统,而 AOSP 一方面为了方便项目的独立开发,另一方面也为了方便对部分组件进行定制,拆分成数百个 Git 项目。为了更好地管理这些仓库,创建了 Repo 工具进行批量的 Git 仓库管理。Repo 是基于 Git 构建的工具,因此,它的工作流与普通的 Git 工作流类似,它的存在是为了让 Git 在如此大的项目系统中更加好用。
一个完整的使用 repo 管理的项目由三部分组成:
以 AOSP 为例,根据功能和模块,项目包括了数百个 Git 仓库,比如 framework 目录下有多个 Git 仓库,这些仓库就是众多的子项目仓库。而不同的 AOSP 版本、不同的定制产物版本,包含的子项目不完全相同,因此,通过一个 Git 仓库来管理各个版本的子项目信息,这个仓库就称为 Manifest 仓库。Repo 工具通过 Manifest 仓库里的信息对整个项目中的子项目进行操作,而 Repo 工具实际上是由一系列的 Python 脚本组成的,这些 Python 脚本通过调用 Git 命令来完成功能,这些脚本本身也通过 Git 仓库来管理,这个仓库就称为 Repo 仓库,并且我们每次执行 Repo 命令的时候,Repo 仓库都会对自己进行一次更新。
若要直接查看安装 Node.js 的正确姿势,请拉到文章最后一节。
一般情况下,你第一次安装会这样:
首先到 Node.js 官网下载压缩包。下载得到 node-vXxx.tar.xz
,然后解压到 /opt/
(适用于共享用户)或 /usr/local/
(适用于用户个人资料)。以 /opt/
为例:
1 | $ cd ~/Download |
然后将 /opt/node/bin
添加到 PATH
环境变量中,这样就可以从任意终端中执行 npm
命令了。确保环境变量生效可以执行命令看是否可以查看 node 版本。
1 | $ node -v |
在过去 CPU 非常昂贵的时候,通常通过设定任务让其不间断执行以提高效率,而在今天几乎所有的计算机在大多数时间都是空闲的,运行的是事件驱动系统(Event Driven System)亦或叫响应式系统(Reactive System)。可以回忆下常听到的“中断(Interrupt)”一词。
响应式系统通常没有开始与结束的概念,而是始终运行着,只在处理事件(Event)时才获得控制权,实际执行的动作由事件与所处的状态(State)共同决定,而当前的状态与过去的事件顺序相关,因此,整个系统都是由事件驱动的。事件很大程度上以不可预测的顺序和时间到达,因此软件每次运行时调用的代码的路径很可能不同。
状态机模型明确地声明了事件的处理依赖于事件与状态。当然你也可以使用条件语句和标志实现状态记录与事件响应,但这其中的可维护性与复杂度可想而知。状态机通过将状态和行为封装在一起,解决庞大分支语句带来的阅读性差和不方便扩展的问题,降低程序的复杂性,提升灵活性。
我们所说的状态机实际上是指 FSM(Finite State Machine,有限状态机),它表示有限个状态以及在这些状态下执行动作和状态转移等行为的模型。FSM 可分为两种类型:
本文旨在解决在不同电脑上都能维护博客或配置、发布的内容丢失可恢复的问题。
观察部署到仓库的内容,我们可以看到上传的内容是 public
文件夹下的所有内容。事实上 hexo-deploy-git
插件是通过拷贝 public
文件夹内容到 .deploy_git
文件夹下,然后提交推送到远程分支上实现了网站文件的部署。
那我们的备份思路也可以这样,上传目录下的其他所有文件就可以了,同时我们不能修改博客的发布分支,因此考虑备份其他所有文件到新分支中。
最简单直接的方法就是在仓库创建一个新的分支,把本地所有的内容都上传到该分支上。但这样会备份一部分不必要的文件,例如 public
文件夹内容,它可以再次生成,就没有必要备份。
那具体要备份哪些文件呢?
每个技术人多少都应该写几篇博客,可以选择发布在各大平台如:简书、掘金等;也可以发布于自己搭建的博客。
本文记录了基于 Hexo 框架 + GitHub 搭建个人博客的过程,你可以按照此文进行实践,也期待看到你自己的博客。
本文的实践基于 Deepin 15.11, 博客地址:Mupceet
Hexo 的介绍及详细信息请查看官方文档,以下记录实操的具体细节。
1 | $ sudo apt install git |
Hexo 文档中写的 Git 的安装命令为 sudo apt-get install git-core
,这是因为老一点的 Ubuntu 中有一个软件也叫 GIT(GNU Interactive Tools),所以 Git 只能叫 git-core
了,后来因为 Git 的名气实在太大,所以 GNU Interactive Tools 就改名了,git
就变成了真正的 Git。
随着业务的发展,程序的功能复杂度也在增加,我们需要开关某些功能、变更功能的参数范围、修改业务的文案、调整界面的显示参数等等,这些功能的变更点都可以称作配置项。
小萌新把这些配置直接硬编码在代码中,每次都勤勤恳恳地找到对应的代码进行修改;后来,老油条把这些配置提取成配置文件,应用通过加载配置文件就完成了业务功能的开关控制,变更时只要找到对应配置项修改一下即可。
因此,我们可以知道配置文件是一个集中记录了配置项的文件,它会影响应用的行为,即同一份程序代码在不同的配置文件下会有不同的行为。
大家发现只要改改配置文件就可以改变 APP 的行为表现真是太 awosone 了,干脆把配置文件拿到服务器上,这样更新配置文件后,通过网络下发给应用,就不用再麻烦开发工程师变更发布应用版本了。看起来,配置文件简直是公司产品运营的上帝啊,只需要程序员发一个应用版本,以后就不需要程序员了。
当然,很显然这种事情是不可能的,因为应用的变更实际有不同的可能,从应用的逻辑来看都发生了变更,但不同的变更可以有不同的处理方式。
后台提了一个需求,要求用户输入上传的内容中不能带 Emoji。网上有一些资料,都提到了过滤 Emoji 的方法,但都存在多过滤或少过滤的情况。我从官方的标准资料入手,希望能解决掉这个问题。
那我们先看看 Emoji 有什么特征。
Emoji 就是可以在文字中输入的表情符。想必大家都用过:
😄😊😃😍😉
看到这些图标,不用多说了吧。当前正式标准为 11.0 版本,Emoji 是 Unicode 的一部分,它在 Unicode 中有对应的码点( CodePoint),也就是说,Emoji 符号就是一个文字。
根据 Emoji 维基百科说明,当前版本中共有 1212 个 Emoji ,实际上这指的是单码点的 Emoji,而还有一些 Emoji 是通过多个码点组合而成。
例如”零宽度连接符”(ZERO WIDTH JOINER,缩写 ZWJ)U+200D
。将U+1F468:男人
U+1F469:女人
U+1F467:女孩
这三个码点使用U+200D
连接起来,U+1F468 U+200D U+1F469 U+200D U+1F467
,就会显示为一个 Emoji 👨👩👧,表示他们组成的家庭。如果用户的系统不支持这种方法,就还是显示为三个独立的 Emoji 👨👩👧。
例如如代表肤色的(U+1F3FB–U+1F3FF): 🏻 🏼 🏽 🏾 🏿 ,发色的(U+1F9B0-U+1F9B3),组合起来后得到同一个表情的不同肤色版本,这一特性在国际大厂的输入法上可以看到,例如 Apple、Google、Samsung 的输入法上都可以输入。
例如 U+1F1E8
U+1F1F3
组合起来成了中国国旗。
由于多码点组合的存在,可以显示的 Emoji 实际上数量多于 1212 个。
最近有几个 Bug 报了崩溃问题,但是奇怪的是 Log 中没有 FATAL EXCEPTION
相关的堆栈信息,经过查找,找到以下一句记录:
1 | 02-06 17:26:30.246 815 989 I ActivityManager: Killing 27917:com.xxx.weather/u0a83 (adj 800): crash |
这个问题分成两个部分来解析,一是查看这个 crash Log 是如何打印出来的, 一是为什么没有打印出 crash 的堆栈信息。
从源码中搜索查看该 Log 在哪里打印,进行原因回溯。
在源码索引中搜索 \"Killing
,从搜索结果中很容易定位到该 Log 所在的文件:
1 | // ProcessRecord.java |