作者归档:贺 利华

关于贺 利华

正在学习编程,享受编程 热爱文学,闲来读读《读库》 有思想,没理想 正在学会专注

【利器系列】00-写在前面

最近跟好友「孔雀67」聊了多次关于「一个到了要被大厂优化的35岁的高龄程序员,接下来要干些啥?」这个话题,由于我俩的革命友谊建立已有 14 年之久,更有长达 8 年之久居同一屋檐下,除去一同求学的 4 年同窗同宿之谊,更有 2 年共同创业背靠背作战的经历,所以我俩之间的通话基本上能做到毫不保留,也非常地简单纯粹。

谈话中,好友谈及自己近期开启了一个新的 Side Project —— 花十年乃至更长的时间,做一个优秀的体素游戏引擎,从他的嘴里说出来这样的话,让我听着感觉非常的信服和幸福。

信服来自于好友近 5 年在体素游戏领域的深耕,自己从零开始,带领一个原本是做移动互联网 App 的团队成功转型,从一个开源的小引擎入手,持续迭代 3 年,从技术到产品,一点点创造和打磨出来一个非常优秀的体素游戏,在商业上获得了不错的成绩。基于这 5 年前的判断,这 5 年间的投入和产出,以及这些年他在该领域解决的各种难题,积累下来的经验和解决方案,我相信他的这个 Side Project 非常的真实可触及,我要先祝福他。

幸福来自于我自己对好友的羡慕,羡慕他能有如此明确的想做的事情,而且听着又是那么切实际和可执行的项目,同时还是一个那么契合自己对长期主义比较推崇的这个心理,在我看来,「花十年乃至更长的时间,做一个优秀的体素游戏引擎」这是一个长期来看都很有意义的事情,未来价值不会消解甚至可能会增长的 事情。

反观自己,从 10 年开始移动互联网创业,从移动社区到手游,再从手游回到互动娱乐直播,从 Android 开发到 Unity3D 开发,再回到 Flutter 开发,感觉自己做过的事情不老少,但是留下的东西少之又少轻于鸿毛,在技术领域也没有什么深厚的积累,在商业上更是未获得什么可以称得上成绩的结果。

所以当 2022 年开始,我就尝试不断地问自己,「除了做一个互联网公司的工具人,我还能做些啥?」,直到最近,一直都没有一个接近好友「花十年乃至更长的时间,做一个优秀的体素游戏引擎」这样的一个可执行的想法或事情作为答案出现。虽说当年大学毕业求职的时候,最终选择了来北京加入一个软件公司,成为了一名软件开发人员,但是自己对于通过代码创造一些东西这个事情,一直没有那种在别人的文本中渲染的为代码痴迷的热情。只是出于养家糊口需要有一技之长,和出于为事情负责任的心态,持续在做着写代码这个事情,在写的过程中只是觉得自己应该干得漂亮一些,不能做得太糟糕,不想丢人或者辜负别人的期望,才一步步走到了现在这个样子。

写代码这件事情并非我所爱(也许可能自己也不知道自己真正热爱的是啥,更有可能是自己做啥就烦啥吧,可能就是因为没有做出来啥成绩罢了)这个事实,慢慢地我学会了接受它,我也接受了我并不讨厌写代码这个事实,同时也接受了我写代码还不太烂的这个事实,终于,我发现了自己只是一个非常非常普通的程序员,只是在写代码赚钱,并尽量让这个过程不那么狼狈和难看。

接受了自己没有这么强烈的创造欲和探索欲之后,内心反而坦然了一些,那么问问自己喜欢做点啥,哪些事情做得还不错,做哪些事情能让自己内心有一些满足感,那么我就做这个吧。

持续创业了 10 年之多,虽然没有进过什么大厂见世面,但是 10 年的在一线创业团队中的摸爬滚打,让我在解决问题上的能力得到了非常充分的锻炼,我也可以摸着自己的心口说一句,在这点上我并不怵,而且我自己也比较享受跟人分享我是如何锻炼自己解决问题的能力的过程,而且自认为这件事情做得还不算太糟。解决问题的能力听起来很虚,但实际上是可以具象化的,而且是可以分模块拆解的。在我自己的逻辑里头,解决问题的能力可以拆解为以下几点:

  1. 理解问题的能力,这是解决问题的第一步,也是很多人不太重视或者较容易忽视的一点,很多的时候我们能否正确地通过对现象(很多时候我们都是遇到了某个具体的事情或者观察到了某个现象)的分析,尝试确定问题对于我们最终找到解决方案至关重要,如果第一步就走错了,后续很有可能要绕很多弯路才能抵达正确的地方;
  2. 分析和定位问题的能力,通常当我们理解了问题之后,基本上我们已经知道问题的方向和可能出现问题的地方了,然后顺着在上一个步骤中发现的一些蛛丝马迹抽丝剥茧地找到问题的源头,抓到这个虫子🐛,然后把它给治了,通常这个步骤是大家日常花费时间和精力最多的,也是大家八仙过海各显神通的环节,每个人抓虫🐛的方法各有千秋,但实际上是有技巧优劣之分和效率高低之别的(别跟我说黑猫白猫抓到老鼠就是好猫这种没有用的话,大家都在一个商业社会里,大家也都是有血有肉的人,大家实际一些,考虑一下投入产出比和抓虫人的个体感受,好不好);
  3. 归因和总结的能力,在解决了问题之后,能否回过头来思考一下,为何在自己的代码中或者项目中出现这样的问题,并且得出结论最终形成自己思考,为自己或团队后续的工作提供一些参考或者指导,并且能够形成自己或团队的一些积淀,就更是善莫大焉了。

👆以上三点,第一和第三点,看着很虚,但是实际上是对人要求更高的软能力,第二点是非常实际的硬技能也是每一个开发人必须具备的恰饭技能。

由于第二点中涉及的更多的是我们日常开发和排查问题过程中需要使用到的硬技能,也是更好展开来聊聊的问题,毕竟这也是难度可低可高,深度可深可浅的一个话题,咱们可以由浅入深,慢慢展开。所以我们就先从分析和定位问题的能力开始,而分析和定位问题中,我们会使用到诸多的工具来帮助我们,正所谓「工欲善其事,必先利其器」,而且我在工作了 10 多年之后,观察了一些伙伴们在分析和定位问题中使用的方法和工具,觉得大家还是有些苦于没有更好地利用到我们可以利用到的更优秀的一些工具和方法,导致自己排查问题的过程并没有那么有效率,体感也相对较差,总是略显狼狈或者磕磕绊绊的。

那么我就先开这个坑——「利器系列」,在这个系列中,我会跟大家分享一下,这些年里头我自己常用的一些工具和方法,以及如何利用这些工具和方法来达成我们「善其事」的目的,希望能给感兴趣的伙伴们提供一些参考或思路上的开拓。关于如何提升自己的软能力的话题,我们留着后面再来一起探讨,咱们不急。

做了两个转换 Color HEX Codes 的 PopClip 插件

最近这三年里头,我成了一个 Flutter 开发人员,加入了映客这家做直播的公司,主要做直播相关的业务开发。映客的产品研发流程中设计团队的设计稿交付通常都是通过蓝湖来完成的,我们也就习惯使用这个工具来查看设计稿了,开发的过程中确认尺寸和取色的过程基本上都是直接在蓝湖上完成。

通常我们需要使用的颜色值在设计稿页面右侧的标注栏中根据我们想要的颜色格式,在 HEX、AHEX、HEXA、RGBA、HSLA 这几种颜色表达格式中随意切换,然后直接拷贝即可。

但是由于我们做的是 Flutter 开发,Flutter 原生支持的颜色构造方法有以下几种:

const Color(int value) : value = value & 0xFFFFFFFF;

const Color.fromARGB(int a, int r, int g, int b) :
    value = (((a & 0xff) << 24) |
             ((r & 0xff) << 16) |
             ((g & 0xff) << 8)  |
             ((b & 0xff) << 0)) & 0xFFFFFFFF;

const Color.fromRGBO(int r, int g, int b, double opacity) :
    value = ((((opacity * 0xff ~/ 1) & 0xff) << 24) |
              ((r                    & 0xff) << 16) |
              ((g                    & 0xff) << 8)  |
              ((b                    & 0xff) << 0)) & 0xFFFFFFFF;

每次从蓝湖中拷贝过来的 HEX Color Codes 字符串总是无法直接拷贝粘贴到 Dart 代码中直接使用,每次要么得自己把 #FFFD3666 中的 # 换成 0x,最终变成 Color(0xFFFD3666) 这样才能正常构建出来一个颜色值对象。对于这种简单重复的劳动,我是有种本能的反感,在前两年的开发中,我自己实际动手写 UI 控件的机会不多,因为组内有其他能做得更好和更熟练的伙伴在负责 UI 控件这块儿,这近一年由于自己从原来的大项目组调整到了更小的团队中,由于人力配置的问题,日常开发工作中也开始自己写一些 UI 控件了。一次次地拷贝中,除了想着想把一些颜色值做成主题(更多依赖于研发和设计高度认同,严格遵守规范,定义好业务内不同场景下应用的颜色、尺寸、圆角半径等等),还有就是想着能不能把每次手动改动 # 符号为 0x 的这种机械式的动作简化掉。

恰巧我很多年之前使用过 PopClip 这款软件,具体为何我会购买这款软件,以及当时我用这款软件来帮助我完成什么事情,我已经记不起来了,但是我非常清楚地记得它有一个非常强大的插件生态和插件能力。所以我就想着是不是可以利用它的能力,帮助我达成每次拷贝到这种 HTML 的 Hex Color Codes 字符串的时候,弹出一个处理选项按钮,我直接点一下就帮我处理好了,我只需要切到我的 IDEA 代码编辑器中直接粘贴就好了,所以我这就直接先去这个官方整理的插件页面去找了一圈,不过看来这种需求还是有点小众,并没有完全匹配的。

想来想去,还是忍不了这样总是无聊的重复劳动,借着周末在家,刚好新项目的研发工作已经阶段性地告一段落了,只需要日常推进持续迭代即可。想着给自己来个代码按摩吧,了解了解这个编程世界中的其他一些美好的角落中的小故事,顺便给自己写个提效的小工具,也算不错,刚好北京近两周正处于疫情苗头又起来了的阶段,也不太能带娃出门。

既然选择要写自己的插件,那就找到官方的教程来读读看,不看不知道,一看吓一跳,真是要给这样的开发者竖大拇哥👍啊,文档写得是真到位,写得真好,但凡作者觉得能对读者有帮助的内容,都给出了外链和应用方法。从这个文档中,我至少拓展阅读或了解了以下一些非常优秀的项目:

quickref

case-anything

 The Noun Project

SF Symbols

ICU specification

作为一个非冲动动手型选手,在动手写任何代码之前,我总是希望能对我即将要做的事情有一个大致的了解后再思考自己需要怎么做。虽然我也能直接拿着官方插件仓库中的代码之间改一改就能跑起来,但我显然一直都不是这样的一个人,我还是比较享受从0到1慢慢了解一个项目,这样难度相对更低,自己也能更舒服,渐进了解了 PopClip Extension 的设计思路和整体规范之后,再了解具体制作的流程和规范,再结合自己要做的事情,匹配到我需要使用的特性,最终确定我需要使用到其 Shell Script Action 的特性来执行我自己稍微熟一些的 python 脚本来完成我想要做的两件事情。

  1. 将 #FFFFFFFF 这样的 HTML Hex Color Codes 一键转换为 0xFFFFFFFF 这样的 16 进制字面常量表示形式;
  2. 将 #FFFFFFFF 这样的 HTML Hex Color Codes 一键转换为整型数 4294967295。

具体的制作过程就不展开了,实际上非常的简单,直接照着教程,创建一个目录,在目录下放上以下三个文件即可:

  1. Config.json => 用于声明这个插件的各项参数和具体需要使用的图标,执行的脚本,以及执行完脚本得到结果后的动作等等;
  2. h2d.py => 这是我写的两个插件中的其中一个插件依赖的 python 脚本的名称;
  3. README.md => 一个用于描述自己插件是干嘛的 MD 文档,可有可无,但是我认为是需要的,像优秀的人和优秀的项目靠近,我们才可能也变得更好一些;

然后将整个目录改名,加一个 .popclipext 后缀在目录名称后面即可,安装了 PopClip 的 macOS 系统会自动识别出来这个目录是一个插件,整个目录的图标展示都会变成 PopClip 的图标样式,双击安装插件,由于我们自己写的插件目录下没有签名文件(如果要签名可以联系 PopClip 的作者帮忙),所以 PopClip 会检测到这是一个未签名的插件,需要我们二次确认后才可安装成功,安装成功之后,即可使用了。

我的这两个插件的效果就是这样的,#FFFFFFFF => 4294967295,0xFFFFFFFF

插件效果演示

最后附上我自己 fork 出来的 PopClip-Extensions 的地址吧:https://github.com/lishali12345/PopClip-Extensions

另外这两个插件的代码分别在:https://github.com/lishali12345/PopClip-Extensions/tree/master/source/Hex2Decimalhttps://github.com/lishali12345/PopClip-Extensions/tree/master/source/HexColorCodes2HexText

下载后可以直接双击安装并使用的插件(注意未签名)在:https://github.com/lishali12345/PopClip-Extensions/blob/master/extensions/Hex2Decimal.popclipextzhttps://github.com/lishali12345/PopClip-Extensions/blob/master/extensions/HexColorCodes2HexText.popclipextz

「读库 App」给我带来了什么?

作为一个《读库》的 13 年长期订户,我从 2009 年毕业那一年开始每年都订阅当年的全年《读库》,在其推出「小册子」计划后每年订阅的就是全年《读库》+「小册子」。

时间由来已久,期间自己搬过大概 6 次家,每次搬家的时候都会发现自己需要搬的书中有近 1/4 是历年来在「读库」这个出版机构购买的各种书籍,每次搬家除了觉得书很沉,收拾起来和搬起来都很累(虽然每次都会找搬家公司,只不过自己每次搬家都是跟搬家师傅一起搬,不论是否有电梯,好像直到最近一次搬家才搬进电梯房,所以每次都有真正的切肤之感)之外,每次收拾这些书的时候还会发现一个巨大的真相,那就是「原来我订了这么多年的《读库》中至少有一半是我竟然都没有拆开塑封的或者没有翻开过的」。

所以每次搬家的时候,会觉得自己辜负了这些好书好文章,没能及时地跟她们在书中厮磨一番,将其冷落了,顺便也会怀疑自己是否还需要持续订阅下去。可是鉴于这些书实在是太便宜了,而买书又那么地能给自己提供一个虚妄的满足感,正所谓「买书如山倒,读书如抽丝」,显然不是我个人的感受和困惑。「买都买了,还需要读吗?」更是我们这帮买书不读人常挂在嘴边的自我开解之辞。所以每年只要老六开始吆喝新一年的饭票要续费的时候,总是第一时间就下单,感觉是给自己这一年的空虚又填上了一锹带有墨香的土。

作为一个卷心菜式的互联网打工人,连续创业多年,连续失败多次的自我压榨者,坦率地讲,这么多年来,一直没能做到传说中的 「work life balance」。作为两个男娃不太合格的爹,工作日基本上没有在 9 点之前下班的时候,留给自己捧读的时间和机会确实不太多。这倒不是想给自己读书不多找什么借口,我也不需要这样的自我承认,活到这个年纪了,自己大概是个什么样的鸟人,基本上自我认知已经比较真实了,就看自己愿不愿意面对了。

坦白地讲,我就是一个在普通不过的普通互联网打工人了,时间不多,疲于奔命,渴望精神世界的自由和财富自由而不得。想进步,每次制定了一个成长的计划后,基本上在 3 ~ 30 天之内就夭折,想健康,基本上在坚持了两周之后以各种各样的姿势再次花式扑街。基本上,大家都看的综艺,我也看一些;基本上,大家都看的电影,我也看一些;基本上,大家都看的美剧,我也看一些;基本上,大家都听的音乐,我也听一些;基本上,大家都买的基金,我也买一些;基本上,大家都炒的股,我也炒一些;基本上,大家犯过的错,我也犯一些;基本上,大家打的鸡血,我也打一些。

看吧,就是这么一个如此普通和无聊的人罢了。所以书买了没读,内在原因在那儿,外在原因在那儿。不过这一两周里,开始尝试使用「读库」App 之后,我发现还是有些变化的。

首先,我已经养成了每天在有空闲的碎片时间时,主动打开「微信读书」App 随便翻翻的习惯。所以当我把「读库」App 跟「微信读书」App 放在手机桌面隔壁时,已经养成习惯的我在想打开「微信读书」的时候,会有一定的概率会打开「读库」。就着这个「裙带关系」,在不到两周的时间里,利用工作日通勤路上的时间,午休的时间,休息日的闲暇时间,我已经读完了《读库 2201》了,而家里的纸质版的《读库 2201》才被翻开了没几回。

其次,由于「读库 App」实际上提供的内容不止限于其出版的《读库》每期刊载的内容,还有其他周边的内容,例如非当期的内容,往期成系列的文章,如我自己花时间最长读着尤为喜爱的《文学的故乡》系列文章。其中关于毕飞宇,莫言,迟子建,这三人的文章我也在往期的《读库》中已经读过了,但是借着这次「读库 App」上的主题系列阅读,我又非常愉快地先重读了一遍,然后接着一口气把刘震云,贾平凹和阿来的三篇文章都给读完了。这一系列的文章,要是从篇幅上来看,已经接近一部小书了,成系列地连续阅读会让人读着读着读出一些勾连和互通的感觉,我能读出这些作家对于自己写作的内源力的探究的殊途同归,我会发现优秀的作家或者说作者实际上他们的认知和行为方式都是那么的诚实,相似处很多,共通性很多,也有着故乡土地给予他们各自不同的底色,更有着不同成长路线给予他们的视角的不同,但是大爱是一样的,那就是书写自己的内心,书写自己看到的普通大众的内心。

借着 App 的便利性,不但不自觉中把原来基本上已经很难再按时读完的书给读了,还因着 App 中编辑的推荐和形式的灵活,有了系统化阅读的快乐和拓展阅读的可能,比如,关于拍了《盲山》和《盲井》的导演李杨的文章,关于区块链原理的文章等等。

认清这个事实了之后,自己蛮开心的,承认自己不是那么爱书的人,已经被手机和 App 驯化成为了一个普通的现代人,那么就借着这个事实,把手边能用起来的时间稍微分配一些给到阅读这件事情就好了,纸质阅读很好,继续保持就好了,手机上的电子阅读也很好,可以补充很多的场景,并且让阅读这件事情完成。

不要为了某种形式,追求某种完美,也不要因为缺失某个条件就不去做某件事情。大概就是这样吧。

「作者此处有删节」是一种什么样的体验?

这几日在读贾平凹的《废都》,之前读过《秦腔》和《浮躁》,想着把这名家的代表大作都读了吧,就在微信读书上找了来读,读着读着就感觉不太对了。诸多章节出内容中,直接使用了「此处作者有删节」这样的文字代替了大段的性描写,这倒不是咱们没读过小黄书,想看看这香艳刺激的场面具体是咋描写的,而是这样奇怪地保留作品的完整性而又要符合出版审查制度的自我阉割显得实在是过于行为艺术了。我甚至觉得这是一种反讽,也行是我过度解读了啊,作者兴许只是想让这本书的出版不那么艰难,也能让这么好的作品给更多的普通读者能读到罢了。

至此我的好奇心就被激起来了,我到要看看删节的内容具体都是个啥。于是我就搜索了一下,还真找到了未删节版的 mobi 和 epub 文件,最终选了一个看着还算满意的转换了格式,导入到了朋友送我的 Kindle 里头,自己调整了一下字体大小和行间距,就开始读了起来。

其实我们的贾平凹先生对于这种香艳场面的描写并没有特别出彩和骇人听闻之处,基本上跟我们实际生活中的性行为过程毫无区别嘛,也没有像小黄书那样为了满足读者猎奇的心理,刻意将性过程的描写扭曲和夸大,只是用词非常的准确和直白,在我们这个比较偏爱委婉美和谈性色变的主流文化审美环境中,可生存的空间确实不太大。

不过在对比阅读的过程中,发现了两个还蛮有意思的事就是,微信阅读的基础排版会让人读起来舒服不少,早年间的 epub 电子书基本上跟纯 txt 电子书毫无区别,全然没有任何排版,错别字频出(可能跟早年输入法和录入员的素质有关?或者这就是个盗版的电子式,何谈录入员)。在Z-Library找《废都》的同时,我也搜索了一本自己手上有纸质本和微信读书版本的《贪婪的多巴胺》,想着放到 Kindle 上读起来不费眼睛,将其导入到 Kindle 上一打开,这个排版和字体,完全就是纸质本的翻版啊,读起来舒服得很,相较而言微信读书的版本就是有些差点意思了,微信读书上的排版基本上都是以铺满手机屏幕为主(为了在窄小的手机屏幕上展示足够多的内容这个可以理解,不知道墨水屏版本对于微信读书中的内容是否有区别设计和适配,如果仅仅是简单的按比例放大,那就有点遗憾和不够了),而 Kindle 的排版由于设备尺寸相对固定并且比较接近口袋本的尺寸,所以整体排版还是很有书籍本体的那种边距的变化,段落感也会很明显,尤其对于我这次是先从纸质版开始阅读的,然后微信读书才上架了电子版,最后我又阴差阳错地读了一个 Kindle 版本,还真是不同的载体体验很是不一样呢。

【开发日志-00】给 Flutter Plugin 加一个自己需要的特性

【开发日志-00】给 Flutter Plugin 加一个自己需要的特性

开个坑,公开记录一下填坑的过程,如果烂尾了,也给自己打个脸。往年每次年底做总结的时候,会惨兮兮地发现这一年都白瞎了,啥进步没有,感觉又枉费这美好人间,腆个逼脸在本上写下明年一定要参与一个什么什么开源项目,然后本子都不知道到哪儿去了,到了又一年年底都忘了当时是不是立了啥具体的 Flag,只是依稀记得,好像自己又打了一次自己的脸,立了 Flag 但是没有立住。

虽说这个公开记录在互联网上多如牛毛,咱们这个犄角旮旯也照不进来啥阳光,估计也没啥人能看到,但是至少不会像本子一样最后找不到了(当然如果本子好好保留时长回顾也是很好的),姑且咱们假设这次可能有用吧,谁知道呢,或者到了明年这个时候,我们发现这个小破站也无法访问了,或者压根儿就没人在意,我自己也不把这次打脸当回事呢,是吧。


从 19 年 6 月开始,我就开始做 Flutter 开发的相关工作了,到现在也已经 2 年半时间了。由于我们做的项目是在线直播相亲业务,很多直播间类型都是强交互的,经常调试的时候会同时连接多台设备,分别调试不同的角色在直播间的行为,例如主播端、连麦用户端、观众端。开发调试的过程中,经常改了一些 UI 布局和逻辑代码后,想着利用 Flutter Hot Reload 或 Hot Restart 的特性来快速调整验证,但是当我想在特定的某一台设备上执行 Flutter Hot Reload 的动作时,却总是找不到合适的方法来快速实施,最终我只能通过 IDEA 底部的 Tool Window Run 或者 Tool Window Debug 中侧边栏的重载按钮在每台连接的设备上都执行一遍,然后通过日志输出中的 Launching lib/main.dart on PDPT00 in debug mode... 的设备名称来区分当前是在那台设备上执行的。这让我觉得一点都不酷,也不知道众多 Flutter 开发者平时是否有更好的其他小妙招之类的,兴许这个插件的开发人员们平时很少会有连接多台设备同时调试的需求吧,既然我有这个需求,而且一直都蛮强烈的,那么我就自己尝试开个坑自己填吧。

由于我自己常用的 IDE 是 JetBrains 的 Intellij IDEA,所以我自己首选的先是解决我自己的问题,从 Flutter Plugin for IntelliJ 入手吧。

我直接打开了 Github,搜索 Flutter Plugin for IntelliJ 找到了官方的仓库 https://github.com/flutter/flutter-intellij 顺手到了自己的仓库下,然后先 clone 下来。在等待仓库 clone 的过程中,我就开始阅读这个项目的 README 了,出人意料的是,我完全没有想到这么多人每天都在用的插件的官方 repo 的 README 中竟然没有关于如何编译和开发这项目的任何文档,最终我是通过这个 repo 的 issue tracker 中的 contributing guidelines 文档才找到了相关的指引文档。但是坦白讲,折腾经验还算丰富的我,按照文档一步步执行下来,最终还是败下阵来了——Gradle Build失败了。按照失败的各种错误提示,各种 Google + Stackoverflow + 官方的 issue tracker 还是没能解决我的问题,索性那么我们就把这个当个长期坑来看吧,先学习一下如何开发 IntelliJ 的插件,然后再看如何改这个 Flutter Plugin for IntelliJ 吧。


刚好再重看了一遍这个 repo 中的 README 中的 Getting Started with IntelliJ 文档,刚好看到了其中关于 Running and debugging 的内容,如下图:

所以,我把我刚刚说的无法快速在某台指定设备上执行 Flutter Hot Reload 行为的胡话收回,说明我原来用的姿势不对,确实没有发现这么简单和常用的功能(当然实际上我肯定是用过的,只是这个操作区域跟我时常需要关注的 IDE 底部的 Console 离得太远了,所以慢慢地就忽略了这个入口了,更多的时候是直接使用了 Tool Window Run/Debug 中顶部的 Flutter Hot Reload 和 Flutter Hot Restart 按钮来实现的,对了 Flutter Hot Restart 只在底部的 Tool Window Run/Debug 中才有哦),由于平时经常需要关注 Console 中输出的日志信息,所以养成了关注底部窗口的相关,操作也一贯是在这个窗口上执行的,但是这个 Window 中只显示了一个 main.dart 的标题,如下图:

如果能在这个标题上加上一个当前执行的设备的名称,是否会更直观一些呢,例如显示 main.dart on V2057A 或者 main.dart@V2057A 这样是不是就更好了呢。嗯哼,这就是我想做的事情了。

坑已开,等着填。我要开始学习了,IntelliJ Platform SDK 会是我们的第一站,我会一点点记录学习过程中所得的。