Android Weekly Issue #255

April 30th, 2017

Android Weekly Issue #255

本期内容包括: 一种在RxJava中显示loading/content/error的好的处理方法; Android O中的一些隐藏宝藏; Uber app的immutable的数据升级; MVP模式下, 不要再做view != null的判断了; 用Dagger2实现的依赖注入; 迁移应用到Kotlin; 如何把Gradle插件从Groovy迁移到Kotlin; Activity中的静态start方法使用; Firebase的实时数据库使用.

ARTICLES & TUTORIALS

LCE: Modeling Data Loading in RxJava

作者介绍了一种方法, 用RxJava来处理显示loading/内容/错误的逻辑.

核心思想是中这个结构把数据包一层:

// Lce -> Loading / Content / Error
class Lce<T> {
public static <T> Lce<T> data(T data) {
// implementation
} public static <T> Lce<T> error(Throwable error) {
// implementation
} public static <T> Lce<T> loading() {
// implementation
} boolean isLoading(); boolean hasError(); Throwable getError(); T getData();
}

然后实际处理的代码就变成了这样:

  repository.getDataEventStream().subscribe({ event ->
if (event.isLoading) {
view.showLoading(true)
} else if (event.hasError()) {
view.showError(event.getError())
} else {
view.showData(event.getData())
}
})

怎么构建这个Observable呢:

Observable<Lce<Data>> getDataEventStream() {
return api.getData()
.map(data -> Lce.data(data))
.startWith(Lce.loading())
.onErrorReturn(e -> Lce.error(e))
}

更多构建方法见原文.

Hidden Gems of Android O

作者仔细看了Android O的API Diff, 然后发现了一些隐藏的宝藏拿出来分享.

  • Storage Access Framework的改进.
  • RecoverableSecurityException.
  • SharedPreferences支持更换底层实现.
  • SmsManager.createAppSpecificSmsToken()提供的更好的短信验证流.
  • 锁屏情况下的显示处理: Keyguard.dismissKeyguard().
  • 全屏Activity的旋转处理.

Engineering Stability in Migrations

Uber的数据类生成及迁移到Immutable Collections的过程.

Don’t put view != null checks in your Presenters

如果你使用了MVP模式, 并且你的presenter在configuration变化时是一直存在的, 那么你的presenter至少会有下面两个方法:

void attachView(View)
void detachView()

这样的话你的getView()方法应该被标记为@Nullable, 然后你就需要在很多地方做null判断, 即便有些地方你100%地肯定View肯定不为null.

Presenter的方法直接从View中被调用

比如那些View中UI控件点击导致的调用.

加个view != null的判断有一个缺点就是如果attach时出现了问题, 这时用户点击了按钮却没有反应, 这个错误会被忽略和隐藏起来. 在这种View应该存在的情形下, 如果得到了null, 应该及时抛出异常发现错误.

It’s always a bad sign when the else branch is missing.

解决方案: 加个@NonNull View getViewOrThrow()方法:

@Nullable
public MyView getView() {...} @NonNull
public MyView getViewOrThrow() {
final MyView view = getView();
if (view == null) {
throw new IllegalStateException("view not attached");
}
return view;
}

在Presenter中异步调用View

很多时候我们需要异步调用View的方法, 这时候我们就不能用getViewOrThrow()了, 因为View被detach是一种合理的情况.

这时候我们如果加个if (view != null)是可以解决这个问题的, 但是却是一个错误的选择. 因为else分支的缺失, 用户可能错过了server返回的结果, 然后永远地等下去.

一个比较好的解决方案就是ThirtyInch, 它有一个方法叫sendToView(ViewAction), 它会推迟ViewAction的执行, 到View再次被attach的时候执行. 如果View已经处于attached的状态, 那么就立即执行.

一个例子:

public class MyPresenter extends TiPresenter<MyView> {

    public void onSubmitLogin(final Credentials credentials) {
mLoginService.login(credentials).subscribe(
success -> {
sendToView(view -> view.close());
},
error -> {
sendToView(view -> view.showError(error));
});
}
}

注意请不要过度使用sendToView().

如果你用MVI模式, 维护一个ViewModel, 在变化的时候渲染到View, 同样也可以删掉view != null的判断. 见My take on Model View Intent (MVI) — Part 1: State Renderer.

Optional和WeakReference

这篇文章中用了view == null作为View被detached了的依据. 如果你使用了其他的包装, 比如WeakReference或者Optional, 你虽然不用null判断了但是并不代表你解决了问题, 你需要做其他的判断并且lint不能帮你做提示了.

结论

你并不需要if (view != null)检查:

  • 当你确定View是attached时, 使用getViewOrThrow().
  • 当View可能会是detached时, 使用sendToView(ViewAction), 来支持else的处理.

Dependency Injection in Android with Dagger 2

一个用了Retrofit和MVP模式的应用, 用Dagger2做依赖注入的例子.

How we made Basecamp 3’s Android app 100% Kotlin

作者他们如何把应用改为用Kotlin.

Migrate a Gradle Plugin from Groovy to Kotlin

如何把一个用Groovy写的Gradle插件转化成Kotlin写的.

Object Oriented Tricks: #4 Starter Pattern

在Activity中定义一个静态的start()方法, 把需要放在intent中的参数都当做方法参数传进来.

Android Studio对此有一个内置的模板, 你只要输入starter, 按回车就可以生成这个方法.

Using Firebase as a Real Time System

Firebase的Real Time Database.

数据库存储的信息以NoSQL的形式放在Google Cloud上.

三个主要的优点: 实时,离线处理, 自动同步.

文中展示了基本的用法.

之后提供了实时数据库的几种使用思路:

LIBRARIES & CODE

Bubble-Picker

气泡选择器.

UltimateAndroidReference

Android资源收集, 包括库, 开源项目, 书籍博客等等.

litho-picasso

为Litho写的picasso库.

Android Weekly Notes Issue #255的更多相关文章

  1. Android Weekly Notes Issue #230

    Android Weekly Notes Issue #230 November 6th, 2016 Android Weekly Issue #230. Android Weekly笔记, 本期内容 ...

  2. Android Weekly Notes Issue #227

    Android Weekly Issue #227 October 16th, 2016 Android Weekly Issue #227. 本期内容包括: Google的Mobile Vision ...

  3. Android Weekly Notes Issue #237

    Android Weekly Issue #237 December 25th, 2016 Android Weekly Issue #237 这是本年的最后一篇issue, 感谢大家. 本期内容包括 ...

  4. Android Weekly Notes Issue #229

    Android Weekly Issue #229 October 30th, 2016 Android Weekly Issue #229 Android Weekly笔记, 本期内容包括: 性能库 ...

  5. Android Weekly Notes Issue #222

    Android Weekly Issue #222 September 11th, 2016 Android Weekly Issue #222 ARTICLES & TUTORIALS Fo ...

  6. Android Weekly Notes Issue #221

    Android Weekly Issue #221 September 4th, 2016 Android Weekly Issue #221 ARTICLES & TUTORIALS And ...

  7. Android Weekly Notes Issue #219

    Android Weekly Issue #219 August 21st, 2016 Android Weekly Issue #219 ARTICLES & TUTORIALS Andro ...

  8. Android Weekly Notes Issue #236

    Android Weekly Issue #236 December 18th, 2016 Android Weekly Issue #236 本期内容包括: Google的物联网平台Android ...

  9. Android Weekly Notes Issue #235

    Android Weekly Issue #235 December 11th, 2016 Android Weekly Issue #235 本期内容包括: 开发一个自定义View并发布为开源库的完 ...

随机推荐

  1. Android的Framework分析---5 ActivityManager分析

    Android系统开发交流群:484966421 OSHome. 微信公众号:oshome2015 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font ...

  2. The network connection was lost 文件下载错误提示

    假设出现这种错误,可能是模拟器断网,重新启动下模拟器就能够:The network connection was lost

  3. php excel文件导出之二 图像导出

    PHP文件导出 之图像 和 文字同一时候导出 事实上之前写了个php文件导出.跟这个极为相似,由于项目须要对图像进行导出.查询一番.又写了一个, 这个能实现图像的导出(仅仅能是本地图像,不能使用远程图 ...

  4. robotframework使用之 下拉框的选择

    选择下拉框有几种方式处理,首先在浏览器F12选择下拉框 1. F12后看见下拉框的源码是<option xxx> <select class="w_60" dat ...

  5. QTreeWidget 的用法

    Qt QTreeWidget 新建一个Qt Widgets Application,拖拽一个Tree Widget 到 ui 界面上,最后实现的效果如下: 添加代码 //test.h //在头文件里添 ...

  6. Cocos2d-x 3.1.1 学习日志2--error:仅仅有静态常量整型数据成员才干够在类中初始化

        今天遇到比較低端的一个问题,就是成员的初始化问题,编译器也无法验证,不同的编译器有些能过有些不能过,我也不知道为什么,总是我们以vs为准吧,以为我们用的环境就是它,话不多说.解决方式例如以下: ...

  7. 一步一步实现一个简单的OS(简单的让boot载入setup)

    这次直接写用boot载入setup模块. 文件系统就先不弄了,以后再说, 咱先整个转简单的载入器. 我把软盘引导改成硬盘了,由于硬盘的读扇区函数简单一些. 这里没有做硬盘的mbr区,我认为在如今我的这 ...

  8. jdbc 链接池的优化

    package cn.itcast.jdbc.datasourse; import java.sql.Connection;import java.sql.DriverManager;import j ...

  9. ASP.NET数据库连接字符串的加密与解密

    ASP.NET web.config中,数据库连接字符串的加密与解密. 虽然不怎么新鲜,但相信还是有许多人不知道,好,不说废话,直接给方法:开始--->运行,输入cmd,接着输入以下内容 加密: ...

  10. python学习(六)元组学习

    元组就是列表的一种,不过元组具有不可变性,而且是用圆括号访问的. 索引(下表索引或者键索引都是用的中括号) #!/usr/bin/python # 这节来学习元组, tuple, 基本上就像一个不可以 ...