Don’t Store Data in the Application Object

There is always some information that is needed in many places in your app. It can be a session token, the result of an expensive computation, etc. It is often tempting to avoid the overhead of passing objects between activities or keeping those in persistent storage. A pattern that is sometimes suggested is to dump your data in the Application object with the idea that it will be available across all activities....

七月 5, 2018 · 4 分钟 · LengYue

Gson中使用泛型

JSON字符串数组 ["Android","Java","PHP"] 当我们要通过Gson解析这个json时,一般有两种方式:使用数组,使用List。而List对于增删都是比较方便的,所以实际使用是还是List比较多。 数组比较简单 Gson gson = new Gson(); String jsonArray = "[\"Android\",\"Java\",\"PHP\"]"; String[] strings = gson.fromJson(jsonArray, String[].class); 但对于List将上面的代码中的 String[].class 直接改为 List.class 是行不通的。对于Java来说List 和List 这俩个的字节码文件只一个那就是List.class,这是Java泛型使用时要注意的问题 泛型擦除。 为了解决的上面的问题,Gson为我们提供了TypeToken来实现对泛型的支持,所以当我们希望使用将以上的数据解析为List时需要这样写。 Gson gson = new Gson(); String jsonArray = "[\"Android\",\"Java\",\"PHP\"]"; String[] strings = gson.fromJson(jsonArray, String[].class); List<String> stringList = gson.fromJson(jsonArray, new TypeToken<List<String>>() {}.getType()); 注:TypeToken的构造方法是protected修饰的,所以上面才会写成new TypeToken<List>() {}.getType() 而不是 new TypeToken<List>().getType() 泛型解析对接口POJO的设计影响 泛型的引入可以减少无关的代码,如我现在所在公司接口返回的数据分为两类: {"code":"0","message":"success","data":{}} {"code":"0","message":"success","data":[]} 我们真正需要的data所包含的数据,而code只使用一次,message则几乎不用。如果Gson不支持泛型或不知道Gson支持泛型的同学一定会这么定义POJO。 public class UserResponse { public int code; public String message; public User data; } 当其它接口的时候又重新定义一个XXResponse将data的类型改成XX,很明显code,和message被重复定义了多次,通过泛型的话我们可以将code和message字段抽取到一个Result的类中,这样我们只需要编写data字段所对应的POJO即可,更专注于我们的业务逻辑。如:...

七月 5, 2018 · 1 分钟 · LengYue

Kotlin在Android上令人惊叹的技巧

Kotlin在Android上令人惊叹的技巧 原文链接 : Kotlin awesome tricks for Android 原文作者 : Antonio Leiva 我已经在这个Blog里讨论了很多Kotlin了,现在Google也正在讨论Kotlin,Kotlin 1.0 RC 已经发布了,毫无疑问,Kotlin不仅仅是Android的一个替代选择。Kotlin就在这里,我推荐你开始学习它。 在Android上我从哪里开始学习Kotlin? 这里已经有一些信息了,但是如果你想要真正的关注和快速学习,我推荐你这些资源: Kotlin reference:如果你想深入了解这个语言的细节,这里是你能找到的最好的地方。我所知道关于这个语言的最好参考文献之一。 This blog:这个链接是我整理的所有关于Kotlin的文章的地方。你不应该错过它,文章属于初级和中级。 Kotlin for Android Developers, The book:如果你想快速和持续的学习,这本书是最好的方法。如果你已经了解了Andriod,这将是一个在你的项目中使用kotlin的快速途径。我已经编写很长一段时间了,当新版本发布的时候我就会更新它。已经更新到了Kotlin 1.0 RC。除此之外如果你订阅了这个列表,你将收到免费的头5个章节和这本书末尾显示的一个购买折扣。 展示这个技巧 在我要讲解之前,有一个要说明的是Kotlin能给你带来简化的Android代码。这里有一组没有特定顺序的独立的例子。 ####### 简洁和趣味的编写点击监听事件 Java 7上编写监听和回调事件非常繁琐的原因是缺少了lambdas。Kotlin有非常好的lambdas和与Java库有非常好的兼容性。用lambda一个方法即可映射接口。你可以这么做: myButton.setOnClickListener { navigateToDetail() } 这就是所有。 为什么layout要如此麻烦的inflate?再也不是了! 当你在Adapter中实例化时,你需要inflate一个layout,你会这样写: LayoutInflater.from(parent.getContext()).inflate(R.id.my_layout, parent, false); 为什么父类不能inflate它自己的layout?好了,用Kotlin你可以。可以创建一个扩展的方法为你所用: fun ViewGroup.inflate(@LayoutRes layoutRes: Int, attachToRoot: Boolean = false): View { return LayoutInflater....

七月 5, 2018 · 3 分钟 · LengYue

RelativeLayout与LinearLayout性能上的比较

首先必须明确: RelativeLayout 性能可未必比LinearLayout高 LinearLayout 性能也未必比RelativeLayout高 不同场景下,性能各有差异。 RelativeLayout在onMeasure 的时候,每个子View都得测量两次的。 所以View树越顶部,越不应该使用RelativeLayout,当然也不应该使用LinearLayout的权重(weight)属性,因为它也会导致测量两次以上。 如果当前布局在View树的底部,那就可以遵循扁平化布局的设计原则。 所以没有绝对的,得根据你的UI设计的结构来决定到底使用哪个。 为什么有些人说,LinearLayout的性能好,另一些人说RelativeLayout好,当然这是有前提的。LinearLayout在不使用weight属性的情况下,越靠近树的顶部,子View越多,性能比RelativeLayout越高。 那么如何选择:其实就围绕着 1、子View数量,嵌套关系。 2、该节点在View树的位置。这两点来综合考虑

七月 5, 2018 · 1 分钟 · LengYue

RxJava操作符分类

ReactiveX的每种编程语言的实现都实现了一组操作符的集合。不同的实现之间有很多重叠的部分,也有一些操作符只存在特定的实现中。每种实现都倾向于用那种编程语言中他们熟悉的上下文中相似的方法给这些操作符命名。 本文首先会给出ReactiveX的核心操作符列表和对应的文档链接,后面还有一个决策树用于帮助你根据具体的场景选择合适的操作符。最后有一个语言特定实现的按字母排序的操作符列表。 如果你想实现你自己的操作符,可以参考这里:实现自定义操作符 创建操作 用于创建Observable的操作符 Create — 通过调用观察者的方法从头创建一个Observable Defer — 在观察者订阅之前不创建这个Observable,为每一个观察者创建一个新的Observable Empty/Never/Throw — 创建行为受限的特殊Observable From — 将其它的对象或数据结构转换为Observable Interval — 创建一个定时发射整数序列的Observable Just — 将对象或者对象集合转换为一个会发射这些对象的Observable Range — 创建发射指定范围的整数序列的Observable Repeat — 创建重复发射特定的数据或数据序列的Observable Start — 创建发射一个函数的返回值的Observable Timer — 创建在一个指定的延迟之后发射单个数据的Observable 变换操作 这些操作符可用于对Observable发射的数据进行变换,详细解释可以看每个操作符的文档 uffer — 缓存,可以简单的理解为缓存,它定期从Observable收集数据到一个集合,然后把这些数据集合打包发射,而不是一次发射一个 latMap — 扁平映射,将Observable发射的数据变换为Observables集合,然后将这些Observable发射的数据平坦化的放进一个单独的Observable,可以认为是一个将嵌套的数据结构展开的过程。 roupBy — 分组,将原来的Observable分拆为Observable集合,将原始Observable发射的数据按Key分组,每一个Observable发射一组不同的数据 ap — 映射,通过对序列的每一项都应用一个函数变换Observable发射的数据,实质是对序列中的每一项执行一个函数,函数的参数就是这个数据项 can — 扫描,对Observable发射的每一项数据应用一个函数,然后按顺序依次发射这些值 indow — 窗口,定期将来自Observable的数据分拆成一些Observable窗口,然后发射这些窗口,而不是每次发射一项。类似于Buffer,但Buffer发射的是数据,Window发射的是Observable,每一个Observable发射原始Observable的数据的一个子集 过滤操作 这些操作符用于从Observable发射的数据中进行选择 Debounce — 只有在空闲了一段时间后才发射数据,通俗的说,就是如果一段时间没有操作,就执行一次操作 Distinct — 去重,过滤掉重复数据项 ElementAt — 取值,取特定位置的数据项 Filter — 过滤,过滤掉没有通过谓词测试的数据项,只发射通过测试的 First — 首项,只发射满足条件的第一条数据 IgnoreElements — 忽略所有的数据,只保留终止通知(onError或onCompleted) Last — 末项,只发射最后一条数据 Sample — 取样,定期发射最新的数据,等于是数据抽样,有的实现里叫ThrottleFirst Skip — 跳过前面的若干项数据 SkipLast — 跳过后面的若干项数据 Take — 只保留前面的若干项数据 TakeLast — 只保留后面的若干项数据 组合操作 组合操作符用于将多个Observable组合成一个单一的Observable...

七月 5, 2018 · 2 分钟 · LengYue

于Fragment和Activity之间onCreateOptionsMenu的问题

Fragment和Activity一样,可以重写onCreateOptionsMenu方法来设定自己的菜单,其实这两个地方使用onCreateOptionsMenu的目的和效果都是完全一样的,但是由于Fragment是从属于activity的,因此第一次使用onCreateOptionsMenu的时候需要注意以下知识点。 一、在Activity和Fragment中onCreateOptionsMenu的实现是有细微差别的: 在activity中: @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return super.onCreateOptionsMenu(menu); } 在Fragment中: @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.pictrue_list, menu); super.onCreateOptionsMenu(menu,inflater); } 两者不同的地方在于 (1)一个有返回值(boolean类型),一个没有返回值。 (2)Fragment中onCreateOptionsMenu的参数多了一个MenuInflater 二、想让Fragment中的onCreateOptionsMenu生效必须先调用setHasOptionsMenu方法 一般我们是在nCreate中调用 setHasOptionsMenu(true); 三、如果Fragment和Activity都同时inflate了一个menu资源文件,那么menu资源所包含的菜单会出现两次 为什么呢,因为inflater.inflate(R.menu.pictrue_list, menu)方法的作用其实就是将第一个参数中包括的菜单项追加到menu中。一开始,在activity中menu是空的,当调用了getMenuInflater().inflate(R.menu.main, menu) menu中便有了菜单项,而在执行到Fragment的(Menu menu, MenuInflater inflater)时,activity的menu就传递下来,作为第一个参数。activity和Fragment中的menu其实是一个对象。 我还可以从上面的分析中得出,Fragment的菜单项会显示在Activity菜单项的后面。 为了解决menu资源所包含的菜单会出现两次这个问题,一般我们让Activity和Fragment inflate两个不同的菜单(就如上面的例子),Fragment会继承Activity的所有菜单。 四、如果在Fragment和Activity中有相同的菜单元素,并且activity和fragment都对此菜单有响应的话,那么将执行两次响应事件。 除此之外,该菜单元素会显示两次。

七月 5, 2018 · 1 分钟 · LengYue

给 Android 开发者的 RxJava 详解

前言 我从去年开始使用 RxJava ,到现在一年多了。今年加入了 Flipboard 后,看到 Flipboard 的 Android 项目也在使用 RxJava ,并且使用的场景越来越多 。而最近这几个月,我也发现国内越来越多的人开始提及 RxJava 。有人说『RxJava 真是太好用了』,有人说『RxJava 真是太难用了』,另外更多的人表示:我真的百度了也谷歌了,但我还是想问: RxJava 到底是什么? 鉴于 RxJava 目前这种既火爆又神秘的现状,而我又在一年的使用过程中对 RxJava 有了一些理解,我决定写下这篇文章来对 RxJava 做一个相对详细的、针对 Android 开发者的介绍。 这篇文章的目的有两个: 给对 RxJava 感兴趣的人一些入门的指引 给正在使用 RxJava 但仍然心存疑惑的人一些更深入的解析 RxJava 到底是什么 RxJava 好在哪 API 介绍和原理简析 1. 概念:扩展的观察者模式 * [观察者模式](#toc_5) RxJava 的观察者模式 2. 基本实现 1) 创建 Observer 2) 创建 Observable...

七月 5, 2018 · 13 分钟 · LengYue

Android Intent 用法全面总结

调用拨号程序 // 给移动客服10086拨打电话 Uri uri = Uri.parse("tel:10086"); Intent intent = new Intent(Intent.ACTION_DIAL, uri); startActivity(intent); 发送短信或彩信 // 给10086发送内容为“Hello”的短信 Uri uri = Uri.parse("smsto:10086"); Intent intent = new Intent(Intent.ACTION_SENDTO, uri); intent.putExtra("sms_body", "Hello"); startActivity(intent); // 发送彩信(相当于发送带附件的短信) Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra("sms_body", "Hello"); Uri uri = Uri.parse("content://media/external/images/media/23"); intent.putExtra(Intent.EXTRA_STREAM, uri); intent.setType("image/png"); startActivity(intent); 通过浏览器打开网页 // 打开Google主页 Uri uri = Uri....

七月 2, 2018 · 2 分钟 · LengYue