Johnny Shieh

人如果没有梦想,跟咸鱼有什么分别


  • 首页

  • 分类

  • 归档

  • 标签

  • 读书

  • 小伙伴

  • 关于

  • 搜索

Android 命名规范与编码风格

发表于 2016-12-22 | 分类于 Android | | 阅读次数

在团队开发项目中,统一的命名规范与编码风格非常重要,只有这样才像一个优秀团队开发的产品。而且这样方便阅读其他人的代码,便于后期维护。我觉得 Android 源码的可读性很好,风格统一,而在实际项目中经常看到混乱的风格,缩进有的是tab有的是space,命名有的是中文拼音有的是英文,看上去非常的乱。相信大家都喜欢简洁整齐的代码,这就需要团队成员稍微牺牲下个性,遵守统一的规范,自己读起来也赏心悦目。下面我根据自己的一些编码规范和网上的一些资料整理出一套 Android 命名规范,至于编码风格是根据 Google 的提供的 Android code style 略微修改而成,直接在 Android Studio 导入即可, 所以下面主要是介绍命名规范内容。

Android 命名规范

下面的命名规范,有些是我个人习惯,有不喜欢的地方可以复制后修改即可,做到简单易记就好,便于团队成员遵守。

基本命名方式

  1. 大驼峰命名法(UpperCamelCase):所有单词的第一个字母大写

  2. 小驼峰命名法(lowerCamelCase):除首单词外,其余所有单词的第一个字母大写

  3. 下划线命名法(case1_case2):单词与单词之间用下划线间隔,所有单词小写

一般建议用来命名的单词简单明了,不要用中文拼音,找个词典翻译下还能提高自己英文水平。有些单词可以写成一些约定俗成的缩写,也可以根据团队成员间的约定进行缩写命名。

阅读全文 »

Parcelable vs Serializable

发表于 2016-12-07 | 分类于 Android | | 阅读次数

前言

Parcelable 和 Serializable 都是实现序列化的接口,那么序列化具体是指什么呢?序列化是指把对象转换为可传输或可存储的状态,反序列化是把序列化后的内容转换为之前的对象。

下面分别讲述两者的设计初衷与具体实现的不同。

Serializable 接口

设计初衷

Serializable 是为了完成对象的持久化,方便保存到本地文件、数据库、网络流等,为对象提供标准的序列化与反序列化操作。

使用

使用 Serializable 来实现序列化非常简单,只需要继承 Serializable 接口:

1
2
3
4
5
6
7
8
9
10
11
public class Person implements Serializable {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

但是经常看到有人实现 Serializable 接口时,还会添加静态变量serialVersionUID,这是 Serializable 对象的版本标识 ID。如果像上面的一样没显示声明的话,默认这个 ID 会根据类的声明和它的成员通过 hash 计算出来。这个版本 ID 会在序列化过程中包含进去,并在反序列化过程中检测,如果本地的serialVersionUID与序列化数据中的不一致,反序列化就会失败并抛出InvalidClassException。

序列化 ID 在 Eclipse 下提供了两种生成策略,一个是固定的 1L,一个是随机生成一个不重复的 long 类型数据(实际上是使用 JDK 工具生成),在这里有一个建议,如果没有特殊需求,就是用默认的 1L 就可以,这样可以确保代码一致时反序列化成功。

阅读全文 »

Android 性能优化之内存泄漏

发表于 2016-11-18 | 分类于 Android | | 阅读次数

在 Android 开发的过程中,经常需要注意内存泄漏问题,不然很容易导致 OOM 问题,或者因此引起频繁 gc 造成 app 卡顿。下面这篇文章将分析内存泄漏的原因、Android 内存管理的相关内容,并分享一些检测泄漏的方法和如何避免内存泄漏。

内存泄漏的定义

Android 是基于 Java 的,众所周知 Java 语言的内存管理是其一大特点,不用像 C 语言那样处理对象的内存分配到回收的全部过程。在 Java 中我们只需要简单地新建对象就可以了,Java 垃圾回收器会负责回收释放对象内存。这么看的话,垃圾回收器会管理内存又怎么还会发生内存泄漏呢?

其实 Java 中的内存泄漏的定义是:对象不再被程序所使用,但是由于这些对象被引用着导致 GC(Garbage Collector)不能回收它们。

下面这张图可以帮助我们更好地理解对象的状态,以及内存泄漏的情况

左边未引用的对象是会被 GC 回收的,右边被引用的对象不会被 GC 回收,但是未使用的对象中除了未引用的对象,还包括已被引用的一部分对象,那么内存泄漏久发生这部分已被引用但未使用的对象。

接下来还有一个疑问:未使用的对象被谁引用会让 GC 无法回收呢?

阅读全文 »

深入分析 ThreadLocal

发表于 2016-11-02 | 分类于 Android | | 阅读次数

这篇文章主要分析 Android 中的 ThreadLocal 原理以及相关问题,也分析与其在 Java 中内部实现的区别,让大家理解 ThreadLocal 的使用场景与正确使用方法。

ThreadLocal 的定义

Android 源码中描述:

Implements a thread-local storage, that is, a variable for which each thread
has its own value. All threads share the same {@code ThreadLocal} object,
but each sees a different value when accessing it, and changes made by one
thread do not affect the other threads. The implementation supports
{@code null} values.

实现了线程局部变量的存储。所有线程共享同一个 ThreadLocal 对象,但是每个线程只能访问和修改自己存储的变量,不会影响其他线程。此实现支持存储 null 变量。

从上面的定义看出,关键的地方即:ThreadLocal 对象是多线程共享的,但每个线程持有自己的线程局部变量。ThreadLocal 不是用来解决共享对象问题的,而是提供线程局部变量,让线程之间不会互相干扰。

下面看在 Android 中 Looper 的应用,每个线程只有一个 Looper 对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
/**
* Return the Looper object associated with the current thread. Returns
* null if the calling thread is not associated with a Looper.
*/
public static Looper myLooper() {
return sThreadLocal.get();
}

在了解 ThreadLocal 的作用后,也会产生一些疑问:

线程局部变量是怎么存储的?

是怎么做到线程间相互独立的?

接下来在分析 Android 的 ThreadLocal 源码的过程中,理解其实现原理,并解决上面的疑问。

阅读全文 »

[译] Android 中使用 ArrayMap 和 SparseArray 替代 HashMap

发表于 2016-10-19 | 分类于 Android | | 阅读次数

这篇文章将讲述在 Android 开发中为什么以及什么时候用ArrayMap和SparseArray替代 HashMap。

在需要存储 key -> value 键值数据时,最先想到的就是HashMap。但是在使用 HashMap 时,Android Studio 会提示用 ArrayMap 替换 HashMap,下面就让我们探索 ArrayMap 的内部原理,以便知道什么时候用 ArrayMap 更好。

HashMap vs ArrayMap

HashMap 所在包:java.util.HashMap

ArrayMap 所在包:android.util.ArrayMap 和 android.support.v4.util.ArrayMap

support.v4 包中的是为 android 低版本提供兼容的。

HashMap 和 ArrayMap 都支持 key 为 null,都是线程不安全的。

下面是 ArrayMap 源码中的文档说明:

ArrayMap is a generic key->value mapping data structure that is designed to be more memory efficient than a traditional HashMap. It keeps its mappings in an array data structure — an integer array of hash codes for each item, and an Object array of the key/value pairs. This allows it to avoid having to create an extra object for every entry put in to the map, and it also tries to control the growth of the size of these arrays more aggressively (since growing them only requires copying the entries in the array, not rebuilding a hash map).

Note that this implementation is not intended to be appropriate for data structures that may contain large numbers of items. It is generally slower than a traditional HashMap, since lookups require a binary search and adds and removes require inserting and deleting entries in the array. For containers holding up to hundreds of items, the performance difference is not significant, less than 50%.

中文大致为:

ArrayMap 是一种泛型键值映射的数据结构,比传统的 HashMap 更节省内存。它通过数组来存储映射关系 – 一个 int 数组存储 key 的 hash code,一个 Object 数组存储 key/value 对。这种设计可以避免在插入元素到 map 时创建额外的对象,并且可以更方便地控制这些数组长度的增长(因为长度的增长只需要复制数组中的元素,而不用重新创建一个 hash map)。

注意这种实现不适合大容量的数据结构,它会比传统的 HashMap 更慢,因为查询利用二分法查找,新增删除元素需要插入和删除数组中值。对于容量最多上百个的数据来说,性能的差别并不大,低于50%.

阅读全文 »
1…91011…16
Johnny Shieh

Johnny Shieh

我本微末,心向天空

76 日志
13 分类
43 标签
GitHub Weibo Gmail 简书
  • 热门系列
  • Dagger 完全解析(6)
  • AspectJ in Android(3)
  • Kotlin 写 Android 单元测试(4)
  • Kotlin 协程完全解析(5)
© 2015 - 2019 Johnny Shieh
访客数 访问量