动态导航总线 Phoenix – URL Router

在我们 Android 开发过程中,在做页面跳转的时候,一般情况下都是写死了代码逻辑,比如 startActivity(new Intent(context, SomeActivity.class)) 或者使用 scheme URL 方式隐性 Intent 跳转,无论如何,一旦我们写完了代码发布出去后,便无法更改跳转逻辑了,而且传统的 Class 跳转将强依赖目标类文件,造成了模块化开发的困难。

如果这时候某个页面出现了巨大的 bug,我们无法在不更新程序的情况下,动态将它转向到一个专门的 error 页面或者某个临时替代的 H5 Web 页面。

即 A -> B 是一个既定的关系,为了达到动态化,必然需要对整个 App 的导航进行统一处理,经过路由中心分发,这就是 URL Router 要做的事情。

Phoenix-URLRouter 便是这样一个 Android 平台上的 URL Router,实现了路由规则的动态可配置性,AOP,以及方便的参数、数据传递。

特性

继续阅读

Android 复杂的多类型列表视图新写法:MultiType

MultiType

Android 复杂的多类型列表视图新写法,清晰、灵活、模块开发、插件化思想

License maven-central

中文版 | 英文版(English Version)

GitHub: https://github.com/drakeet/MultiType

这几天晚上回家开始设计我的 TimeMachine 的消息池系统,并抽取出来开源成一个全新的类库: MultiType! 从前,我们写一个复杂的、多 item view types 的列表视图,经常要做一堆繁琐的工作,而且不小心的话代码还堆积严重:我们需要覆写 RecyclerView.AdaptergetItemViewType 方法,并新增一些 type 整形常量,而且 ViewHolder 继承、泛型传递、转型也比较糟糕,毕竟 Adapter 只能接受一个泛型……十分麻烦导致过于复杂的页面经常会使用 ScrollView 来实现,一次性加载,而且失去了复用性。

一旦我们需要新增一些新的 item view types ,就得去修改 Adapter 旧的代码,步骤繁多,侵入较强

现在好了,只要三步,不需要修改旧代码,只要无脑往池子里插入新的 type ,会自动连接、分发数据和事件,新增再多的 item types 都能轻松搞定,支持 RV 、复用,代码模块开发,清晰而灵活。若要说为什么这么灵活? 因为它本来就是为 IM 视图开发的,想想 IM 的消息类型可能有多少种而且新增频繁。
继续阅读

当我们谈 XML 布局文件代码的优雅性

当我们谈代码的优雅性,是不可以忽略经常在打交道的 Android XML 布局文件的书写。有人会问,XML 文件内容有什么优雅不优雅的,不都是随便写吗?嗯,是有很多人,根本就没有意识到或者不关心布局文件内容应该怎么写更好看,更漂亮。我觉得,优雅的 Android XML 布局文件的内容,应该做到以下几点:

  • 不能有多余的空行;
  • 不要保留你注释掉的代码(要回溯我们有 git);
  • 尽量避免 hard code(硬编码);
  • 能复用的资源尽量抽出到对应的 value 文件;
  • 尽量消除警告、单词拼写错误;
  • 不要使用废弃的关键词,如 fill_parent、dip;
  • 属性条目要有序;

其中,本文特别想讲的就是最后一条,“属性条目要有序”,属性条目指的是,比如一个 ImageView 节点下的 android:id, android:layout_width, android:paddingLeft, android:src … 等等这些。大部分人在书写 Android XML 布局文件的时候,都是想到一个要设置的属性,就随意在原有的属性们之下一行,再加上一行新属性,这样导致诸如 android:id 有时会在最后一行,有时在一堆属性中间,不仅不利于我们在需要 id 的时候,肉眼查找阅读,也会使得整个 XML 文件内容没有规则,很凌乱。

继续阅读

使用 MailOtto 做预加载

最近我开源了一个专注懒事件的事件总线 MailOtto: https://github.com/drakeet/MailOtto 并写了一个用它来做预加载的实践案例:第一个页面预先为第四个页面发起数据加载请求,等用户进入第四个页面,那加载好的数据才会分发给它,若在数据下来前进入第四个页面,也会等完成的时候自动接收到。

这个数据需要 8 秒,如果进入到第四个页面才开始加载,体验就很不好,就算只要 1 秒,也会有一个文本从无到有闪动的过程。如果在第一个页面停留超过 8 秒,它足够完成全程预加载,进入第四个页面里面就能直接拿到数据,可谓完美预加载。

本文就是来介绍一下这个实践案例。
继续阅读

Android 内存泄漏案例和解析

Android 编程所使用的 Java 是一门使用垃圾收集器(GC, garbage collection)来自动管理内存的语言,它使得我们不再需要手动调用代码来进行内存回收。那么它是如何判断的呢?简单说,如果一个对象,从它的根节点开始不可达的话,那么这个对象就是没有引用的了,是会被垃圾收集器回收的,其中,所谓的 “根节点” 往往是一个线程,比如主线程。因此,如果一个对象从它的根节点开始是可达的有引用的,但实际上它已经没有再使用了,是无用的,这样的对象就是内存泄漏的对象,它会在内存中占据我们应用程序原本就不是很多的内存,导致程序变慢,甚至内存溢出(OOM)程序崩溃。

内存泄漏的原因并不难理解,但仅管知道它的存在,往往我们还是会不知觉中写出致使内存泄漏的代码。在 Android 编程中,也是有许多情景容易导致内存泄漏,以下将一一列举一些我所知道的内存泄漏案例,从这些例子中应该能更加直观了解怎么导致了内存泄漏,从而在编程过程中去避免。
继续阅读

浅谈 Android 编程思想和架构

我主要是想讲一讲自己对于 接口、模块化、MVP 的一些心得。

有这么一个场景,两个不同的页面,包含了看起来一模一样的界面内容(或者称 frame/UI),这种场景可能很常见,有时看到会说:“哈哈,我可以设计个复用!” 但是遇到一个问题是,这两个页面需要分别去请求不同的服务端 API,返回下来的数据结构也不一样(姑且不说去和服务端开发协商),这样就会导致具体的 view holder 或者适配器在绑定数据的时候无法复用,为何说无法复用或难以复用呢?举个例子,比如传进 Apdapter 的 list item 数据内容不一样,你总不能把 item 再拆了,分好几个 list 传进去吧?面向具体编程情况下,适配器得到不同的 items,得对 item 分发数据绑定到 UI,难免要写很多重复的代码。

这时候我们可以采取面向抽象编程,既然不同的数据对应一样的 UI,如果它们都实现了一样的接口,这个接口的设计取决于 UI 需要哪些数据块,然后不同的 Item model 去实现这个接口提供数据即可,这时适配器只要持有这个接口类型的 Item 即可,举个通俗的例子:数据模型1和2都实现了 IPost 接口,那么适配器就只要持有 List<IPost> 数据即可,List<数据模型1> 和 List<数据模型2> 都可以视作“一样的鸭子”传递给这个适配器。这样把数据模型的数据块抽取放到了数据模型本身实现,不仅不用写很多重复的分发代码,而且适配器本身都能复用了;当接口需要新的方法,也能驱动着实现者们去实现。
继续阅读

Retrofit 2.0 + OkHttp 3.0 配置

Retrofit 和 OkHttp 都是伟大的 Square 公司开源的伟大项目。前段时间也是从 Retrofit 1.9 升级到 2.0 beta 4 版本,从 OkHttp 2.+ 版本升级到  3.0.1 版本。这两者在各自的这两个大版本升级中,都改变了不少,使得原本的代码都需要进行一些修改才能使用,我也是稍微摸索了几下,如今大致摸清,把一些基础配置,比如设置 Json 转换器、RxJava 适配器、设置 Debug Log 模式、设置超时、错误重连,以及配置 Access token Interceptor 等等一些内容,分享一下。
继续阅读

一种新的 Header View + RecyclerView 实现方式

在 GitHub 开源了一种新的 Header View + RecyclerView 实现方式,使用 CoordinatorLayout 把 header 抽离出 RecyclerView,并做到上下滑联动,这样 Java 层代码就能简单和简洁很多,更便于刷新和响应,也不用写多 item view type 逻辑。

源代码:

https://github.com/drakeet/RecyclerViewWithHeaderNewPractice

XML 代码层次是这样的:

说明:

  • 可以使用 SmoothAppBarLayout 这个第三方库,它是一个提供顺滑滚动的 AppBarLayout 补足库,这一个层次必须置于 RecyclerView 代码下面,也就是界面上是在 RecyclerView 的上层,这样AppBarLayout 包裹的 header views 才能接收到点击事件(其实根本原因是,RV 对于 Padding 部分也会拦截手势所以不得不这么做)。
  • 如果想要列表上滑的时候,状态栏跟随着滑动显示出阴影效果,可以在 FrameLayout 外再包裹一层 android.support.design.widget.CollapsingToolbarLayout. 可以实现如图效果(注意状态栏阴影):
  • Demo 中的 UI 来自著名的 App Peach,为了避免写太多无关的、具有干扰性的 UI 代码,俺使用了两部分截图来替代繁琐的 UI 实现,在此声明和感谢  Peach.

使用 Python 创建 Telegram 机器人

要说聊天体验,telegram 比微信好很多,微信消息一多就卡,而且没法直接引用消息进行回复导致经常找不到上下文。telegram 则始终异常流畅,记录阅读位置,消息多的时候也不会觉得跟不上聊天节奏或卡 … 当然了,这一段都不是今天要写的这篇文章的重点,这篇文章主要还是要介绍一下如何开发 telegram 机器人,telegram 在去年中旬的时候开放了机器人的 API,可以设置 hook,使得所有消息都能被转发到你的服务上,然后作出自动化回复。

机器人可以被邀请入群做很多辅助工作,比如输入 “/google xxx” 就可以得到谷歌查询的结果等等,甚至还有人开发了 /fff 命令,用来烧死异性恋😂什么的,只要发送一条 “/fff install someone” 的消息到机器人所在的群聊当中即可。总之,利用 bot API 几乎无所不能,也十分有意思。

俺从几天前开始玩耍 telegram bot API,开发了一个属于自己的机器人,@XiaoaiBot,可以回声、计算两个日期的间隔时间、以及帮用户在群里找出最近一个 @ 消息,应该说还是非常好玩的。
继续阅读

2016.2.19 再见

哎 … 春节放假结束了。原本是17号晚上要坐动车回厦门的,结果突然想到忘记见福贵一面了,若是不见可能又要等到一年后,于是改签到今天。

时间过得很快,阿贵也很快就走了。只记得他说我很好看,我也觉得他很好看,然后再见了,我很怀念他 …

那天晚上晓忆请我去看了火影忍者博人传的电影,其实就是昨天晚上,觉得很好,仿佛又一次看到了吊车尾的鸣人成长记,十分感动。原本是打算回来的时候写一篇日记的,结果回来之后又忍不住想写代码,而且觉得应该一会儿就搞定 便可以写日记,结果直到睡觉的时候才完成,日记也就变成今天写了。 继续阅读