分享我的 Android Studio Emacs 风格快捷键

QWERTY 键盘区域,来自 wikimedia

高效地使用快捷键,让手指能在键盘上噼里啪啦地飞舞是加速编码速度的关键,尽量把快捷键控制在打字键区,能显著减少编码过程手腕的移动,让按快捷键更舒服更高效。Emacs 风格的快捷键能通过前缀键来扩展更多打字区的快捷键是个很好的选择(非 emacs 用户可能深痛恶觉)。我这套快捷键也是基于这个原则,首先减少对功能键区的使用,一来容易与系统快捷键冲突,二来手指移动的幅度过大难定位不容形成肌肉记忆,所以只保留编译运行相关的快捷键。至于编辑键区则更次,手腕必须得移动,眼睛也得跟着辅助定位,只保留少部分不常用的默认快捷键。数字键区最糟,手腕移动幅度最大,再说我的 87 键盘都没有小键盘-_-,直接弃用。至于鼠标,那更是万恶之源,整个手臂都得移动,还要眼睛配合才能用鼠标完成一次操作,写代码的过程大多是用鼠标辅助点击几次,然后又回到打字区继续敲,这样来回一次切换成本太高。何况程序员经常用鼠标点点点?多没 B 格啊。虽说如此,不过想要完全不用鼠标还是不太容易,只能说一个命令通过鼠标打开层层菜单来执行超过一次,第二次就应该用 Find Action 来执行,如果一天超过三次那就应该给它设个快捷键并记住。

快捷键都是在 Emacs keymaps 的基础上进行自定义, Android Studio 相比 Eclipse 内置的 Emacs keymaps 强大了许多,不过 Eclipse 有 Emacs+, Android Studio 却没有这方面的插件。所有 Android Studio 相比 Emacs 多了一些不足,比如:

  1. Android Studio 只支持一个前缀键(prefix key),所以 spacemacs 那样的助记法快捷键 Android Studio 难以实现
  2. Android Studio 中 Esc 不能作为修饰键使用
  3. IntelliJ 可以为 Escape 命令配置快捷键,但不少 UI 还是硬编码为键盘的 Esc 键。所以为了退出浮窗,经常要 C-gEsc 交替使用
  4. 不过窗口的操作逻辑不一致,有些 UI 可以用移动光标快捷键,有些只能用方向键

Android 项目打包到 JCenter 的坑

搜索下如何发布 Android 项目的信息,大部分都会找到这篇文章 Publishing Gradle Android Library to jCenter Repository,中文的指引可以看使用Gradle发布项目到JCenter仓库。不过,如果按照这些文章提供的 build.gradle,可能还会遇到一些坑。

调用 getBootClassPath() 出错

具体的错误信息是

Cannot call getBootClasspath() before setTargetInfo() is called.

这个是 gradle 的 android plugin 1.1.0 版本的 bug,见 Issue 152811 - android - Android Gradle Plugin 1.1.0 breaks Javadoc tasks。将插件更新到 1.1.1 以上版本就可以了。

classpath 'com.android.tools.build:gradle:1.1.2'

GBK 编码问题

手伤回顾

这是写于上个月的日记:

八月五号晚和朋友一起踩单车,从东里到隆都再到莲下,最后出国道324再回家,本来没想踩这么远,在东里踩了一段后,发现再继续只有这条路线而已,往回踩又没意思,于是只能继续硬着头皮踩下去。

大概是因为侥幸心理作遂,朋友有带手电,我便不想带了。

隆都那段路路况并不好,偶尔一段路面凹陷,避开了几处,还是有一处避不开,因为没有手电看不清路面,高速(20多)压过去,结果后胎被蛇咬了。泄风不快,不过跑了一段后还是停下来打算换胎。因为随身带的内胎是18/23,而后胎是25的,最后还是决定补胎为好,折腾了一段时间才补好继续上路。

爆胎是其一,真正悲剧是发生在隆都到莲下那段路,一开始路况很糟糕且不说。后面的路面是极好的,因为刚修好,还没有通车。我便开始放松了起来,不自觉速度也快了,不过最多就是二十多,因为一直跟着山地后面。变换下姿势,因为觉得架子比较小,身体伸展不开,便把手放到最远端,手掌朝下按住手变顶部,没留神自己居然这个压到手刹上了,结果车轮抱死,只记得前轮好像打横了,其他还没反应过来整个人就飞出去了,可能是左手先着地,伤得最严重,接着是右手侧身落地,肘关节肿起一块,肩膀在地上磨了一小段,起了一块红点,肌肉痛,幸好衣服没破。右脚膝盖也磨掉一小块皮。

起来后发现左手腕动不了,手腕还得放在大腿上支撑,不然痛得不行,剩下的路程只能一只手骑了,十多公里还是坚持下来了。快到的时候发现还被补了一刀,本来车子无大碍,就是手变被磨伤了,结果回来的路上把 cateye 码表弄丢了,估计是在等红灯的时候,一只手上下车很吃力,试了好几次,估计在那里蹭掉了。本来那个红灯可以不等的…看来人生的戏剧性就是体现在这样接二连三的悲剧中。

浅谈 Recycle 机制

这里的 Recycle 机制并不是指 Java 虚拟机中的垃圾回收机制,而是 Android 框架里十分常用的一种设计模式。基本思想很简单,当一个对象不再使用时把它储藏起来,不让虚拟机回收,需要的时候再从仓库里拿出来重新使用,这就避免了对象被回收后再重分配的过程。对于在应用的生命周期内(或者在循环中)需要频繁创建的对象来说这个机制特别实用,可以显著减少对象创建的次数,从而减少 GC 的运行时间。运用得当便可改善应用的性能。唯一的不足只是需要手动为废弃对象调用 recycle 方法。

如何实现?首先,我们需要一个仓库用于存放暂时不用的对象;需要新对象的时候我们不能使用 new 来分配一个新对象,所以还需要一个方法 obtain 来从仓库里获取对象;最后,便是 recycle 方法了,用于回收不再使用的对象。一个简单的实现如下所示,技术细节在注释里解释:

/**
 * Created by Tiou on 2014/7/15.
 * 一个实现 Recycle 机制的对象
 */
public class Data {
    /**
     * 对象池,就是上文所提到的对象仓库,用于暂时存放不用的对象。
     * 用链表来实现对象池结构,直观,高效,易用。
     * sPool 便是指向链表头部的引用
     */
    private static Data sPool;
    /**
     * 指向链表中的下一个元素,当 next 为 null 时表示已到达链表末端
     */
    private Data next;

    /**
     * 隐藏构造函数,避免对象被 new 关键字创建
     */
    private Data(){}

    /**
     * 从池里获取一个新对象,没有的话则返回一个新的实例
     * @return 可用的新对象
     */
    public static Data obtain(){
        if(sPool!=null){ // 池中有可用的对象
            // 对于对象池来说顺序并没有关系
            // 这里取链表的第一个对象,主要是因为方便
            Data data = sPool;
            sPool = sPool.next;
            data.next = null;
            return data;
        }
        return new Data();
    }

    /**
     * 将当前对象回收,一旦对象被回收,便不能再使用,代码中也不应存有任何到该对象的引用
     */
    public void recycle(){
        clear(); //清理对象
        // 把当前对象作为首元素按入链表中
        next = sPool;
        sPool = this;
    }

    /**
     * 重置对象到刚初始化时的状态
     */
    private void clear(){

    }
}

本地生成二维码的 Chrome 扩展

最近谷歌被全面封杀,用了多年的 QR-Code Tag Extension 基本处于不可用状态,特色版 Firefox 自带有本地生成二维码(QRCode)功能,于是便想找一下 Chrome 有没有在本地生成二维码的扩展,结果没有发现,反而找到了一个 jquery.qrcode.js(主要实现绘制的工作,生成二维码的功能是 QR Code Generator 实现的),一个可在本地生成二维码的 jquery 插件,很易用。想必用它做一个 Chrome 扩展是个很容易的事情,毕竟之前也写过 Chrome 扩展,虽说是两三年前的事。

本来以为一两个小时可以搞定,结果从完善功能到打包发布可能得花掉一天时间,API、流程基本忘光了,都得跟着文档慢慢做。jquery.qrcode.js 中文乱码,让它支持 UTF-8 编码费了不少时间,contextMenus + Programmatic injection 也比较麻烦,还尝试下 i18n,样式用的是 Pure.

可以在 Chrome WebStore 下载 Offline QRCode Generator

  1. 提供了最基本的扩展工具栏按钮,点击可直接为当前标签的 URL 生成二维码,也输入自定义文本来生成。
  2. 支持页面右键菜单,可为当前页面网址,所选文本或所选超链接生成二维码。
  3. 使用 Event Pages 技术,只有当需要时(点击右键菜单的时候)才会加载后台进程。
  4. Lazy Load 技术注入脚本,只有点击右键菜单生成二维码的时候,才会为当前页面注入脚本,不会对正常浏览网页产生影响。

新的主题

当晚上把代码提交到服务器后,我确实后悔了,花了不少时间弄了这个新主题,深深明白这样的行为是在舍本逐末。

写独立博客步入第五年,以为很长,又不过是转瞬。虽然到现在还是没什么内容,但摆弄博客所花的时间其实不少,只不过大部分都用于折腾博客系统本身,从 WP 到静态博客,从 php 到 ruby,php 始终不是一门让人看一眼就能喜欢的上的语言,我想,说 php 是专为 Web 开发设计的语言应该没有问题。不可否认,我对 php 对认识还很浅薄,拿来就用,没有系统的学习过,写过 WP 插件,还有一些 CLI 脚本仅此而已。ruby 则不同,一眼便让人着迷,虽然 ruby 因 Web 而火了起来,不过吸引我的却是它的语法和社区,我接触 ruby 两年来还未用过 RoR,只是用来写各种日常脚本和折腾 ruhoh,各种元编程黑魔法目眩而神迷。现在 ruby 已经代替 python 成为我的日常脚本语言,不过作为日常脚本语言来说 ruby 各种库看起来似乎远没有 python 那么齐全。

对于编程语言了解不深,太多吐槽不适合我,还是不要说太多免得贻笑大方。说回这个新主题,如今改这个主题另一方面又算是对得起自己了,居然可以耐心地先把前端方面的知识系统地了解一下。看了一遍 JavaScript: The Good PartsJavaScript 秘密花园 也是份不错的指引。相信如今写出来 JS 代码会更加「纯正」,现在页面上的不少效果都是自己写 JS 实现的。另外还断断续续翻了不少 SASS And Compass in Action,学了 Sass 和 Compass 才知道原来自己一直都是拿着木棍跟着那些身披战甲手持长枪的骑士后面乱舞一通。阮一峰写过两篇文章介绍 Compass 和 Sass,Compass用法指南SASS用法指南,也可以参考我的 SASS 笔记

当然用上最好的装备,不见得就可以打胜仗。实际上这个主题越做越不讨我喜欢,我一心只想要两栏的响应式布局,结果往边栏塞入了太多东西,又无法舍弃花俏无用的功能(做得那么辛苦起码得放上几个月再说吧),完全无视自己一直奉承的简洁至上原则啊(话说以前要做复杂其实也做不出来),特别把自己的头像弄得那么显眼,看起来很不协调。在大屏上把字号调大了一些,既减少一行的字数,也能避免留白的浪费,确实能提升阅读体验。这次的笔记主题也做得还不错,想要的东西都能做出来,就是还缺点美化。

癸巳年小结

去年5月份的时候日淘了一台 KPW,但如今回想起来去年到现在好像也没读完多少书。看了不少福尔摩斯,一些胡适的书,还有漫画——进击的巨人。小说还看了动物农场、未央歌。最近还看了一本结构化拖延法。实体书好像一本也没有读完,看来看了那么些拖延症的书我的拖延症还是一点也没有缓解,不过心态上倒是变得无所谓了,也算是这些书的正面作用吧。

去年看了多少书没有作记录,现在要回想起来很困难,一直没有可以很方便记录的东西真是很可惜。

我读书还有个怪癖,一些书总不舍得读完,读到最后一章就得歇一歇便不再读下去了,后来又彻底忘了,结果一年两年都没再拿起来,现在想到的就有中有百年孤独,未央歌,禅与摩托车维修艺术,如果能有个东西来提醒就好了。

去年竟然一本与 CS 相关的书都没有,那今年要好好补回来,还是要继续打牢计算机基础,深入理解计算机系统已经蒙尘多年了,不好意思让它继续躺在书架了。如果今年要读一本 CS 的书的话,那就是它了。

笔记之舛·破

这篇文章还有上一篇,文章写得太长看起来太累,还是一分为二较好。这篇就直接说说用 ruhoh 来搭建自己的笔记系统(同文中 notes)的不足和一些解决的想法。去年还在这里大谈静态生成页面的种种好处,如今想来未免太过理想。

优雅的命令行

Ruhoh 提供了完善的命令行接口,实际使用中会发现,操作文档是在 Terminal,编辑文档是在 Emacs,预览文档是在 Chrome,经常需要不断地切换上下文,悲催的是这三个软件都是操作系统般的存在,特别是 Chrome 很容易走神。一旦切换后走神,就会走得很远,短时间内都回不来。这样带来了很大的上下文切换成本,要保持专注就得尽量把时间控制在编辑器内(全命令行自然更少干扰,不过全命令行操作的理想早已离我远去了)。首先要简化操作文档的命令行,个人使用 ruhoh 这个命名空间就可以省略,之前就做个一次简化,但是 notes 方面的操作命令还是很不方便需要进一步修改。至于预览切换方面,得益于 Markdown 的可读性,更多问题像是强迫症,一点点改动就要切换去看效果了,必须暗示自己只有格式方面的修改才需要去看预览。把命令行接口整合进 Emacs 确实是可行的,但是作为一个这么美好的愿景,当前还是想想就好。

Git 有时也是累赘

git 是一个非常流行的版本控制工具,功能强大适用广泛。但有时太强大也不是好事,notes 最需要的还是同步功能,也就是说 git 只是用来构建一个分布式仓库,版本控制反而不是很重要,但现在做一次同步太过繁琐(add、commit、push),每次还都必须写上 comment,而且提交到服务器后都会自动编译发布,一次同步要花费几十秒十分恼人。

# time git push
0.02s user 0.02s system 0% cpu 21.367 total

staticfile.org

无奈 cdnjs 被墙,只能选用国内的静态文件加速服务,可惜都不理想。

幸好发现了 staticfile.org,他引用了 cdnjs 的仓库,同时也拥有自己的国内仓库,库度数量比较多,用了七牛的服务,速度应该可以。

考虑写个 Ruby 的工具方便 ruhoh 使用。

近期評論

友情链接