February 19th, 2017
本期内容: 写好单元测试的几条原则; 如何 mock Kotlin 的对象; 如何消除 God Object -> Context; 如何用 Android 来打电话和发短信, 以及相应事件的监听; 一个监控用电情况的应用 (Android Things);
用 Keystore 保存敏感信息; 依赖注入和 Dagger 2 的使用; Wear 应用向 Wear 2.0 的迁移; 用 ViewPager 构建无 Fragment 的应用结构; Android 应用的压力测试讨论; RxJava 中
注销处理不当引起的内存泄露; 单元测试并不是完全可靠; Trello 向离线模式迁移的架构变化.
- Subscription
本周推荐的代码里有一个顶部提示控件, 一个手势检测库, 还有一个 loading view 的库.
作者关于写好单元测试提供了三条简单的规则以及每条规则对应的一些建议.
尽量在每次改动之后都跑跑测试, 及早发现问题. 你的测试跑得越快你就越有可能经常跑它们.
为了让测试跑得很快:
对每一个 bug 来说, 应该有且只有一个测试挂掉, 并且测试失败的原因应该能从测试方法名上看出来.
这样就迫使你每一个测试只检查一件事情, 导致你的测试小并且简单易懂, 也好维护.
实现 tips:
你的测试应该是完全值得信赖的, 不应该随机失败, 否则你将会对测试失去信任, 也不再会认真对待测试的失败.
所以你的测试应该是 100% 可靠的, 只在真的有问题的时候才失败.
建议是:
因为 Kotlin 中的类默认是
的, 要继承的话需要显示地声明
- final
.
- open
如果只是为了在单元测试中 mock 就要加个 open 吗? 不.
本篇文章就介绍如何如何 mock Kotlin 的对象, 而不用该它的声明.
首先, ; 然后, 使用这个库.
文中详细介绍了使用细节, 以及对
方法的讨论.
- any()
在面向对象编程中, God Objects 是应该被避免的.
在 Android 开发中, 最常见的一种 God 对象是 Context. 本文介绍如何清除这个 God 对象, 同样的方法也可以用来处理其他对象.
首先说为什么要干掉 Context?
在做 TDD 的过程中, 我们希望是面向接口的, 而且我们不应该 mock 非我们拥有的类型.
所以我们不应该直接 mock 外部的 API, 而是应该创建一个自己的接口层.
作者发现很多类其实并不真正需要一个 Context, 它们只是需要得到 string 或者存储的键值对.
之后文中举例介绍了如何通过定义接口摆脱 Context.
如何拨打电话:
- String dial = "tel:" + phoneNo;
- startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse(dial)));
(不需要权限).
如果想在 app 里直接拨出去电话, 需要权限
, 并且改用
- android.permission.CALL_PHON
.
- ACTION_CALL
监控电话事件:
需要权限
. 来监控来电, 打出去的电话需要这个权限:
- android.permission.READ_PHONE_STATE
.
- android.permission.PROCESS_OUTGOING_CALLS
具体实现就是在
注册监听器
- TelephonyManager
. 如果是在 Activity 中需要在对应的生命周期注销监听器.
- PhoneStateListener
如果需要后台监控, 则需要用到
, 过滤 actions 为
- BroadcastReceiver
和
- android.intent.action.PHONE_STATE
. 除了获取相应的电话号码, 还可以进一步阻止电话的拨出.
- android.intent.action.NEW_OUTGOING_CALL
发送短信:
发短信也是两种方法, 启动一个短信客户端程序, 或者直接从程序里发.
启动其他程序:
- Intent smsIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto:" + phoneNo));
- smsIntent.putExtra("sms_body", message);
- startActivity(smsIntent);
自己发: 需要权限
.
- android.permission.SEND_SMS
- SmsManager smsManager = SmsManager.getDefault();
- smsManager.sendTextMessage(phoneNo, null, message, null, null);
注意 Android 6.0 以上的设备, 本文提到的这些危险权限都是需要动态请求的.
收短信:
通过
, 需要权限
- BroadcastReceiver
.
- android.permission.RECEIVE_SMS
作者分享了一个她的 Android Things 的应用 (和 Github repo), 可以监控她家的用电情况.
利用 Android 的 Keystore 来存储一些敏感信息.
一篇依赖注入的介绍文章.
先介绍依赖注入是什么, 有什么优点, 接着介绍 Dagger 2 的使用.
作者把他的 Wear 应用升级到了 Wear 2.0.
一些开发者可能不想选择 Fragment, 这篇文章里有相关讨论: .
作者推荐了一些在不用 Fragment 的情况下构建 App 的库: , , , .
而本篇文章想要展示另一种方法, 既不用 Fragment, 也不用上述的第三方库来构建一个 App -> 用 ViewPager.
在 PagerAdapter 里管理了一个 Presenter 的 List, 每一个 Presenter 管理一个 View. 具体实现见原文.
之前大神 JakeWharton 有一个 Sample App: , 里面有一个 debug drawer, 可以用来模拟不同的测试情形, 比如网络连接不好, 延迟, 或者网络错误等等.
作者他们的 App 也有一个类似的 debug drawer, 他们讨论出了一个需要测试的情形的 checklist:
作者甚至发现其中的一些项目组合起来测试非常有趣.
来源: http://www.cnblogs.com/mengdd/p/android-weekly-notes-issue-245.html