Android Weekly Issue #225

October 2nd, 2016

Android Weekly Issue #225

本期内容包括: Android 7.0的Quick Settings; Firebase; 兼容旧版本的shared element transition; Wear; ORM: 用ActiveAndroid做数据库存储; 崩溃报告工具对比; Google Cast API介绍; Google的播放器库ExoPlayer 2.x发布; 项目的包结构整理; Task API的使用等等.

ARTICLES & TUTORIALS

Android 7.0的快速设置 Quick Settings Tiles

从Android 7.0 (API 24)开始, 任何app都可以创建一个quick settings tile, 快速访问关键功能.

它除了是一个展示最新信息的UI, 点击一个片还可以trigger后台任务, 打开dialog或activity.

一个好的quick settings tile:

决定是否要建立这样一个tile时, 主要考虑紧急性和频繁性两个方面.

每一个tile和一个TileService关联. 和其他service一样, 它需要在manifest中注册, 它的label和icon就是显示在quick settings上的文字和图片.

TileService的生命周期:

TileService是一个bound service, 它的生命周期主要由系统控制. 主要有三个阶段: being added, listening, being removed.

  • onTileAdded(): 当用户添加这个tile到quick settings.
  • onStartListening(): tile变为可见.
  • onStopListening(): tile变为不可见.
  • onTileRemoved(): 用户移除这个tile.

以上这是默认模式, 如果你准确地知道何时更新, 你可以使用active mode.

此时更新的回调onStartListening()是通过静态方法主动触发的.

更新UI:

UI是Tile, 主要包含icon, label, description和state. 最后必须调用updateTile()方法.

处理点击:

onClick()回调触发的时候, 我们可以启动一些后台工作, 或者showDialog(), 或者startActivityAndCollapse().

对于锁屏的机器有一些限制, 不能打开dialog, 并且activity需要有一个特定的flag, 有一个unlockAndRun()方法可以让用户先解锁后做一些工作.

长按tile默认会打开app的app info屏, 当然这个行为也可以override. 只要给你想打开的activity加上ACTION_QS_TILE_PREFERENCES.

Android开发最佳实践 Android Development Best Practices

关于性能:

Best Practices for Performance;

Performance and Optimization

关于架构:

android-architecture

写单元测试和UI测试.

使用Proguard, Stetho.

复用布局, 使用标签.

reusing-layouts.

把launcher icons放在mipmap文件夹下.

多用shape和selector而不是图片.

避免深层次的布局.

向Intent或Bundler传数据时, 使用Parcelable而不是Serializable. 因为后者使用反射而比较慢.

不要在UI线程进行文件操作.

明白Bitmaps. 因为它们占用很多memory. Displaying Bitmaps

使用style来避免重复的属性设置.

需要时使用Fragment.

明白Activity的生命周期.

使用得到公认的libraries而不是自己的实现.

在各种机器上测试.

Recap Of Google Launchpad Build Lagos : All About Firebase

作者参加了一个叫Google Launchpad Build的会议, 这篇文章是总结, 全部是关于Firebase的.

Android Shared-Element Transitions for all

在Lollipop+的设备上, shared element的transition动画很好实现, 但是在旧的版本上该怎么办呢? 作者展示了他的方法:

  • Activity A捕捉origin view的初始值, 通过Intent把它们传给Activity B;
  • Activity B完全透明地启动;
  • Activity B读取bundle中的值, 准备场景;
  • Acitivty B运行shared element动画.

几个实现细节:

需要知道View在B中的位置, 时机是layout之后, 但是draw之前, 即onPreDraw().

返回时只需要把这个动画反向播放即可.

Writing Better Adapters

(这个上一期刚讲过, 不知道为什么重复了. )

就是关于RecyclerView的Adapter, 作者认为多种View类型时, Adapter中太多的instance of和强制类型转换不是一种好做法, 于是提出了他的做法.

Android Wear: Accessing the Data Layer API

Data Layer API是Google Play services的一部分, 用于不同设备(手机和手表)间的数据交换.

作者先提供了代码, 发送和存储数据, 监听数据变化.

问题是, 如果Wear第二次向mobile请求数据, mobile发送了和上一次一样的数据, Wear并不会进入onDataChanged(), 因为数据并没有变化.

所以作者想知道如何从Data Layer API来获取数据, 并展示了他的方法在不同情形下的应用.

Espresso Tests For TextSwitcher

作者想给TextSwitcher写Espresso测试.

从Android Studio 2.2开始, 你可以录制你的操作, IDE将会自动为你生成Espresso测试代码. 但是作者录了一个有关TextSwitcher的测试之后, 跑失败了.

这是因为TextSwitcher继承了ViewSwitcher, 其实现其实是把两个TextView加到了布局里.

所以Espresso抛出了AmbiguousViewMatcherException.

所以作者根据可见性区分了它俩, 修复了测试.

还可以根据child view的index来区分.

Animating Android Activities and Views with Slide Animations

作者展示了如何给Activity和View加上左右滑动的动画.

Guide to ORM using ActiveAndroid: Part 1

这是一个系列教程, 相关的代码在: ActiveAndroid-Tutorial

什么是ORM(Object-Relational Mapping)呢?

a technique to convert between incompatible type-systems in an object-oriented programming language.

在面向对象的语言中, 转换不兼容的类型的技术.

ActiveAndroid是一个ORM(object relational mapper), 让你不用写SQL语句, 就可以读写数据库.

其他类似的工具还有RealmOrmLite.

A Comparison of Android Crash Reporting Tools

作者对比了几种崩溃报告工具, 并介绍了如何使用.

包括: Firebase, Crashlytics, Apteligent, Bugsnag.

Google Play Services: Google Cast v3 and Media

Google Cast是一个让用户把网上的内容发送到设备上的技术. 通常用来和TV交换内容.

作者详细地介绍了如何使用Google Cast SDK来创建应用.

注: 要建造客户端程序, 首先需要注册: https://cast.google.com/publish/.

这是收费的.

ExoPlayer 2.x - It’s here (plus FAQs)!

Google的库google/ExoPlayer升级到v2.x了.

(它是一个Media Player, YouTube用的就是它.)

这次是个重大更新, 添加了很多新功能, 推荐大家以后用新版.

How We Rethought our Complete Package Structure for Buffer on Android

作者他们重新整理了项目的包结构, 总结了整个过程还有从中学到的东东.

作者他们之前的包结构是按类型的, 有activities, fragments, adapters等包. 因为类名以类型终结, 所以索性就按整个分组.

当app变得越来越大, 这种组织方式发现就不太好, 感觉很难找东西, 并且感觉没什么结构.

经过改变之后, 作者他们采用了一种更加整洁并且易于导航的结构.

新结构中, 当添加一个新的feature, 就保持在同一个目录中, 这样就不用来回切换目录.

作者他们的新结构有四个总目录:

  • data
  • ui
  • injection
  • util

data中包含网络请求及相关的models, preferences, database, data models, 还有其他和数据直接关联的东西.

其中和不同API关联的models又分别组织在子目录下.

ui目录中包含所有和UI相关的组件, 在这个包中按照功能又拆分了子目录. 其中有base包, 用来盛放Fragment, Activity和MVP的基类, 接口等; 还有common包, 用来盛放公共控件.

injection中包含所有依赖注入的类, 分component, module和scope的子目录.

util中含有Helper和Utility类.

Become a Firebase Taskmaster! (Part 3)

这是系列文章的第三篇, 这个系列是关于Play services的Task API.

如果项目里已经依赖了Firebase, 变自动包含了Task API, 如果不想用Firebase, 可以单独添加依赖:

compile 'com.google.android.gms:play-services-tasks:9.6.1'

创建新的Task可以用下面这两个方法:

Task<TResult> call(Callable<TResult> callable)
Task<TResult> call(Executor executor, Callable<TResult> callable)

第一个call()方法在主线程执行任务, 第二个call()方法可以把工作提交给一个Executor.

Callable有点类似于Runnable:

public class CarlyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "Call me maybe";
}
}

参数制定了方法的返回值的类型, 进而也是创建出Task的类型.

Task<String> task = Tasks.call(new CarlyCallable());

想要链式执行, 进行后续操作, 可以用Continuation.

public class SeparateWays implements Continuation<String, List<String>> {
@Override
public List<String> then(Task<String> task) throws Exception {
return Arrays.asList(task.getResult().split(" +"));
}
}

它继承接口时指定了输入和输出的类型, 它的输入来自于Task的输出.

可以多写几个Continuation类然后连起来:

Task<String> playlist = Tasks.call(new CarlyCallable())
.continueWith(new SeparateWays())
.continueWith(new AllShookUp())
.continueWith(new ComeTogether());
playlist.addOnSuccessListener(new OnSuccessListener<String>() {
@Override
public void onSuccess(String message) {
// The final String with all the words randomized is here
}
});

LIBRIARIES & CODE

groupie

显示和管理复杂的RecyclerView布局, 把你的items按照逻辑分组管理.

android-junit5

Gradle插件, 用JUnit5做Android的单元测试.

epoxy

用来构建复杂的RecyclerView屏.

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

  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 #221

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

  6. Android Weekly Notes Issue #219

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

  7. Android Weekly Notes Issue #236

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

  8. Android Weekly Notes Issue #235

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

  9. Android Weekly Notes Issue #234

    Android Weekly Issue #234 December 4th, 2016 Android Weekly Issue #234 本期内容包括: ConstraintLayout的使用; ...

随机推荐

  1. s:form标签

    2017-01-07 17:43:18 基本的用法 <!-- Action类必须有一个无参的构造器,因为在执行action方法之前,拦截器已经创建了一个"空"的Action对 ...

  2. 《深入理解Java虚拟机》虚拟机性能监控与故障处理工具

    上节学习回顾 从课本章节划分,<垃圾收集器>和<内存分配策略>这两篇随笔同属一章节,主要是从理论+实验的手段来讲解JVM的内存处理机制.好让我们对JVM运行机制有一个良好的概念 ...

  3. 使用mapreduce计算环比的实例

    最近做了一个小的mapreduce程序,主要目的是计算环比值最高的前5名,本来打算使用spark计算,可是本人目前spark还只是简单看了下,因此就先改用mapreduce计算了,今天和大家分享下这个 ...

  4. 从EF的使用中探讨业务模型能否脱离单一存储层完全抽象存在

    上次赶时间,就很流水账地写了上次项目对EF的一次实践应用模式,因为太长了,也没能探讨太多,所以再继续扩展. 这次想探讨的是,实体,如果作为类似于领域模型的业务模型存在,它的数据能否来自不同的数据源.这 ...

  5. MySql中in和exists效率

    mysql中的in语句是把外表和内表作hash 连接,而exists语句是对外表作loop循环,每次loop循环再对内表进行查询.一直大家都认为exists比in语句的效率要高,这种说法其实是不准确的 ...

  6. Python学习--02输入和输出

    命令行输入 x = input("Please input x:") y = raw_input("Please input x:") 使用input和raw_ ...

  7. node入门学习1

    一个普通网站访问过程(1)浏览器向服务器发出一个HTTP请求(2)域名解析为IP地址(3)建立TCP连接(4)浏览器发起HTTP请求(5)服务器接收到HTTP请求,解析请求的路径和参数 出现乱码的原因 ...

  8. 深入分析Spring 与 Spring MVC容器

    1 Spring MVC WEB配置 Spring Framework本身没有Web功能,Spring MVC使用WebApplicationContext类扩展ApplicationContext, ...

  9. 计算机程序的思维逻辑 (47) - 堆和PriorityQueue的应用

    45节介绍了堆的概念和算法,上节介绍了Java中堆的实现类PriorityQueue,PriorityQueue除了用作优先级队列,还可以用来解决一些别的问题,45节提到了如下两个应用: 求前K个最大 ...

  10. Microsoft Build 2016 Day 2 记录(多图慎入)

    Microsoft Build 2016 Day 1 记录 Microsoft Build 2016 进行到了第二天,我觉得这一天的内容非常精彩,因为主要和开发者相关