Skip to content
Ider

沉淀我所学习,累积我所见闻,分享我所体验

Primary Navigation Menu
Menu
  • Home
  • About Ider
    • Who Ider?
    • Why Ider?
    • How Ider?
    • Where Ider?
    • What Ider?

Android

2022-12-08
08 December
On December 8, 2022
In IT Products(数码产品)

Pixel Watch智能手表和Pixel 5, 6 Pro 及 7 Pro手机

上个月我去亲身参加了 Google Android Summit 2022。过去几年因为疫情的关系,各类技术大会都在线上举行,今年终于可以小规模地搬到了线下,让社交变得更近。整个会议讲了很多关于 Android 开发的好货,主要集中在开发工具和 Kotlin 的 Compose,但最让大家激动的是在傍晚结束前送给每个参加的人一个最新发布的 Pixel Watch。这应该是最近5年Google在谷歌各种大会上给的最慷慨的一次了。

第三方厂基于Google配合Android系统手机为手表开发的Wear OS发布过很多智能手表,但是由于各种原因都没有Apple Watch那边受欢迎。Pixel Watch是第一款由Google自己发布的智能手表,紧靠着Pixel手机的产品线。因为是第一款自然跟比较成熟的Apple Watch还是无法比拟。

我个人对手表有比较强的需求,这样我可以随时方便地抬手看时间,而不需要每次掏出手机再点亮屏幕。不过我对智能手表一直没有很大的热情和期盼,一来它的大多功能都还无法取代手机对我而言主要功能还是看时间,而来它的低续航又需要我付出其他的精力去维持它的功能。

所以过去一年里, 我日常使用的是 Fitbit Charge 5,在保持一周左右的续航的同时,还能获得简单的健康和锻炼信息。可能正是因为 Pixel Watch 跟 Fitbit 有自然的继承,让我在 Pixel Watch 的转换感到无比的舒适。在拥有同样的 Fitbit 的功能同时,还有更好的交互界面。虽然续航是最大的短板,最多只能持续24小时,但是基于更好得电池布局其充电速度非常得快,很大程度得弥补续航得不足。另外,每天我也会在洗漱时讲手表摘下拿去充电,并没有感到不便,因此 Pixel Watch 自然成了我的日常佩戴。

 

Pixel Watch有不少 Google 和 Fitbit 出的第一方应用,也可以在Play Store上下载很多第三方应用。由于屏幕过小,我并不是特别习惯使用这些应用。但是也有几个功能我非常喜欢使用。

一个是用手表唤起手机铃声,这样就能很快找到手机;另一个是通过手表来控制在手机上的媒体播放,特别是调节音量,我就不需要拿出手机来控制了。

目前还没有对 Pixel Watch 进行深度发掘,希望以后能有更多的发现和惊喜。

Pixel Phones

自2018年介绍了一下 Pixel 3 XL 手机已经有4年时间了,Pixel系列也到了第7代。中间因为没有看到特别大的提升以及听到的质量问题我跳过了 Pixel 4,但集齐了 Pixel 5,Pixel 6 Pro 和 Pixel 7 Pro。

Read More →

2021-07-09
09 July
On July 9, 2021
In IT Products(数码产品)

我拥有过的无线耳机

之前介绍了我拥有过的四个移动硬盘,讲到我对它们的使用频率其实并不高,使用率也低所以很长时间内不会再购入新款。我使用频率比较高的电子产品,除了手机和电脑以外,最多的还是耳机。前几年对耳机的需求主要在听歌以及降噪让工作更专心,而过去一年多在家工作的日子里对耳机的使用基本全在视频会议上。过去五年里,随着无线耳机的质量越来越好,我根据需求买了五款无线耳机,就来介绍一下我与它们从过去到现在的经历。

我入手的第一款无线耳机是2016年买的Bose QuietComfort 35。在开放式办公室工作我一直期望有一部降噪耳机,如果是无线的就更好了,但在当时对于$350的价格还是比较犹豫的。

一个在Apple的朋友跟我说他们有员工折扣可以买这款耳机。这一下子让我惊讶到原来Apple员工折扣单单可以买Apple自家的产品,还有在Apple Store卖的其他东西都可以。他查了一下可以最后的价格含税差不多是原价的85折,我一下子心动了。当他说下单可以当天就近去Apple Store取货,我立刻把信用卡号发给了他。

这部耳机的好不用多说,降噪功能让我工作时可以非常专心,出差的时候我也会带到飞机上来隔绝飞机上的声响好安心入睡。耳机的音效也是让我最舒适的,完全打压Apple的各种耳机。耳机的电源续航能力也很好,所以一直用到现在。现在耳机垫因为时间原因已经老化破皮了,我还刚刚给它换了新的。

要说不好的地方,夏天带着比较热是一个,但考虑到办公室的空调总是很低这个不是问题;另一个就是比较大也比较沉携带起来不太方便,一般我都留在办公室的抽屉里。最多的状况还是同事有事找我时基本完全听不到他们的声音呼唤,接着就被他们拍肩膀吓到。

Read More →

2021-01-14
14 January
On January 14, 2021
In Design Patterns(设计模式), English Posts(英文写作), Knowledge Base(心得笔库), Mobile Development(移动开发), Software Engineering(软件工程)

ProtoBuf 2.0 method count optimization for android development

The Protocol Buffer library was not initially built for Android, it just turned out to have a Java version to be used in Android, but it’s not optimized for Android apps, for example: it doesn’t consider the method count limit in Android.

So, in this article, I’d like to share some work I found specifically on Protocol Buffer Version 2 that can reduce the method count. If your app is also heavily relying on Protocol Buffer, I hope these approaches are useful for you too.

General Approaches

1. Use Protocol Buffer Java Lite Runtime

Just as the name indicates, the dependency library is much smaller than the regular Protocol Buffer Java runtime, the generated code is also much slimmer. However, the APIs are compatible between those two versions, so the call sites would not be affected when changing the library.

2. Don’t use <Message>OrBuilder interface

For each Protocol Buffer message definition in .proto file, the Protocol Buffer compiler generates an interface named <Message>OrBuilder (<Message> is the name defined in .proto file). This interface would be implemented by the concrete <Message> class and the corresponding Builder.

It might be attractive to use it as a variable type thereby you can depend on abstractions to not concrete classes. But calling methods on Java interface would make Dex take count of those methods.

In reality, every place can directly use either <Message> or Builder, then the optimization tool (like R8, ProGuard) can safely remove the methods declared on the interface.

Special Tricks

Protocol Buffer Java Lite is very good, but if I open the magic box of generated Java classes, I notice it’s still not optimal for Android. There are a couple places I could modify to make it more effective for Android applications.

Instead of copying the Java files and making the change, which is error prone when engineers update the .proto file, I created a script to automate the job. Just add the execution of this script at the end of the Protocol Buffer gradle task, so it works just as a complement of Protocol Buffer code generation process.

[codesyntax lang=”groovy” lines=”normal”]

protobuf {
  protoc {
    artifact = 'com.google.protobuf:protoc:3.7.0'
  }
  plugins {
    javalite {
      artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
    }
  }
  generateProtoTasks {
    all().each { task ->
      task.builtins {
        remove java
      }
      task.plugins {
        javalite { }
      }

      // `getOutputDir()` can only be read during configuration, 
      // so it’s out of action block
      def outputDir = task.getOutputDir(task.plugins[0])
      task.doLast {
          exec {
              commandLine file('protobuf-optimizer.py')
              args outputDir
          }
      }    
    }
  }
}

[/codesyntax]

In the script, I have made the following modification on generated java code.

1. Change the modifier of Builder constructor from private to package

Simply running the sample addressbook.proto from Protocol Buffer tutorial side, you would get a class like the following snippet:

[codesyntax lang=”java” lines=”normal”]

public static final class Person {
    private Person() {}

    protected final Object dynamicMethod(
            com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,
            Object arg0, Object arg1) {
        switch (method) {
            case NEW_BUILDER: {
                return new Builder();
            }
        }
    }

    public static final class Builder {
        private Builder() {}
    }

}

[/codesyntax]

When analyzing the APK file, we could would find some synthetic classes and methods:

This is because the outer class is accessing the private constructor of the inner class. The generated synthetic class would contribute an extra constructor to the Dex file. Therefore, by simply removing the private from Builder(), you can remove such classes and methods.
Read More →

2020-12-15
15 December
On December 15, 2020
In Knowledge Base(心得笔库), Programming Life(程序人生)

面过100场行为面试后

两年前,我在 Facebook 完成了100场面试的里程碑,分享一篇对于面试心得讲了讲面试对我带来的个人能力的提升。今年五月,我差不多在一年半的时间里又完成了100场面试让总数达到了200场。接着到了今年十月份,其中一类面试—行为面试(Behavioral Interivew) 我也完成了100场。感觉是个不错的时机来再来写篇文章分享一下,但这次我没有特别心得体会总结,就聊聊一些随意的想法。

 

美国科技公司对于软件工程师招聘比较常用三种面试形式:写代码(Coding),系统设计(System Design),行为面试(Behavioral)。对于大公司来说,他们常年都会很多招聘指标,也有大量的申请人,所以相对于中小公司,在大公司更容易获得面试方面的培养机会。(Facebook内部对不同类型的面试都有内部代号,但是因为不对新人记忆不友好,慢慢开始弃用了。)

当我作为面试者时,我对它们的难易程度排列为:系统设计>>行为面试>写代码。毕竟代码是可以通过刷题来提高的,行为面试也主要是讲自己的故事,而系统设计的广度和深度的把控就比较不确定了。

而当我变成面试官时,从另一个角度排列顺序就变成了:行为面试>系统设计>写代码。这排位主要根据我写面试反馈结论所花的时间来衡量:一般代码面试的结论我需要5-10分钟完成,系统设计则要15-30分钟,行为面试则尝尝花费我30-60分钟。主要原因是行为面试要做的内容记录就很多,次要原因是英文写作还是我的短板。因此我后来只做行为面试来锻炼我自己的英文写作,同时也让我享受挑战的乐趣。

 

之前的文章我讲了面试在广义层面带来的各种不同的好处,面试了所以不同类型面试后,我想再聊聊各类面试对于作为面试官的软件工程师在公司内的职业发展不同阶段所能带来的特定技能的锻炼和提升。进而让面试者从另一个角度来了解面试的意义和价值。
Read More →

2020-03-12
12 March
On March 12, 2020
In Data Structures(数据结构), Knowledge Base(心得笔库), Language Tips(语言初试), Mobile Development(移动开发)

基础数据类型的包装类的内存大小

谈到 Java 的基础数据类型(Primitive Data Types),可以找到很多关于其种类以及内存大小的文章。基础数据类型对应的包装类(Wrapper Classes)也会介绍自动装箱(Autoboxing)和拆箱(Unboxing),以及带来的效率上的影响。但可能是因为Java一般所使用的环境都有比较充足的内存,似乎从来没有人讨论过每种包装类所占的内存大小以及对内存溢出可能造成的影响。

到了 Android 应用程序开发领域,由于设备硬件本身以及系统对各个程序在资源使用上的约束,就会出现很多特别的使用习惯,比如推荐使用Typedef来替代枚举类型(enum)来减少内存使用和方法数。因此关于基础数据类型的包装类所占内存大小就值得写篇博客来研究一下。

包装类所占内存大小

网上我找了很多计算类内存大小的方法,但是既然我是 Android 工程师,我就用 Android Studio 提供的 Memory Profiler 来查看内存使用情况

下边就是我用来做内存检查的类,它包含了所有基础数据类型和对于的包类型

[codesyntax lang=”java” lines=”normal”]

public class Primitives {
  boolean pBoolean;
  byte pByte;
  char pChar;
  double pDouble;
  float pFloat;
  int pInt;
  long pLong;
  short pShort;

  Boolean cBoolean;
  Byte cByte;
  Character cChar;
  Double cDouble;
  Float cFloat;
  Integer cInt;
  Long cLong;
  Short cShort;

  public Primitives() {}

  public Primitives(Void v) {
    cBoolean = false;
    cByte = 0;
    cChar = '\0';
    cDouble = 0.0;
    cFloat = 0.0f;
    cInt = 0;
    cLong = 0L;
    cShort = 0;
  }
}

[/codesyntax]

接着在 MainActivity 中创建两个 Primitives 类的字段:一个没有初始化对象类型,一个将所有对象类型初始化成默认值。然后运行程序,在 Android Studio 中打开 Profiler 查看内存时”Dump Java heap” 就可以看到这两个 Primitives 对象内存使用情况

从图中的结果可以看出如果对象的值是 null,那他们是不占用空间。在这一点上看,如果字段大部分时间都存的是空值或者以空值指代默认值,那相对比总是会被赋予默认值的基础数据类型在内存使用方面要好一些。

对于包装类,它们都比其对应基础数据类型要占用更多的内存空。仔细对比不难计算出他们的差别都是 8 bytes,正好是一个普通 Object 实例的大小。这也证明的包装类只是对基础数据类型的简单包装。

基础数据类型 包装类型
类型 大小 类型 大小
boolean 1 byte Boolean 9 bytes
byte 1 byte Byte 9 bytes
char 2 bytes Character 10 bytes
double 8 bytes Double 16 bytes
float 4 bytes Float 12 bytes
int 4 bytes Integer 12 bytes
long 8 bytes Long 16 bytes
short 2 bytes Short 10 bytes

所以,使用包装类不仅会有自动装箱和拆箱产生的效率上的影响,对内存的使用也有很大的影响。而 Android 的内存又是稀缺资源,所以 Android 库里多了特殊的数据类型来优化内存的使用,比如 SparseArray 替换以 int 为主键的 HashMap。
Read More →

2019-08-29
29 August
On August 29, 2019
In Data Structures(数据结构), Knowledge Base(心得笔库), Mobile Development(移动开发), Software Engineering(软件工程)

Gradle android-library 的各种坑

软件开发随着项目越来越大,我们会开始拆封出多个子项目(sub-project)或者库(library)来更好地独立维护。Android开发也不例外,我们也会需要创建各种库。如果使用Android Studio和Gradle,他们为我们提供了便捷的方式来创建libray。但是他们也带来了不少的维护问题,本文就来讲讲android-library里的坑来帮助大家避开。

android-library v.s. java-library

对于普通Android手机项目,我们有创建两种不同的Library可以选用: android-library 和 java-library

它们的gradle文件内容分别如下

[codesyntax lang=”groovy” lines=”normal” highlight_lines=”1″]

apply plugin: 'com.android.library'

android {
    // ...
}

dependencies {
    // ...
}

[/codesyntax]

[codesyntax lang=”groovy” lines=”normal” highlight_lines=”1″]

apply plugin: 'java-library'

sourceCompatibility = "7"
targetCompatibility = "7"

dependencies {
    // ...
}

[/codesyntax]

两种库在定义上的根本差别其实就是不同gradle plugin的使用。另一个小的差别就是android-library需要有一个 AndroidManifest.xml 文件,但它可以简单到只有一行内容(其中package的值通常是文件夹的路径)

[codesyntax lang=”xml” lines=”normal”]

<manifest package="com.ider.android.library" />

[/codesyntax]

使用上他们有一些差异,这些差异也是我们决定使用哪种Library的标准:

  • android-library 可以使用 Android API(比如Activity, Service等等),java-library 则不能使用
  • android-library 可以编译android资源文件(resources files),java-library 则无视这样内容
  • android-library 编译出 arr 文件,java-library编译出 jar 文件(本质上他们都是 zip 文件)
  • android-library 的配置可以包含各种编译类型(build variants)来控制,java-library没有那个复杂
  • android-library 可以依赖于另一个android-library 或者 java-library, java-library只能依赖于java-library而不能依赖于android-library

总体而言 android-library 基本是 java-library 的一个超集, 但 android-library 比 java-libray 使用起来要更加复杂一些。从上边的对比来看,对于Android的项目,因为我们不确定什么时候会需要调用 Android 的API,或者定义一下 Android 的资源内容。再者最后一条的约束也决定了创建的 java-library 要保证在整个依赖树(dependency tree)上要在接近叶子节点的位置。所以不如优先选择创建android-library,以免掉入之后改 build.gradle 的坑中。
Read More →

2018-12-16
16 December
On December 16, 2018
In English Posts(英文写作), Knowledge Base(心得笔库), Programming Life(程序人生)

Insights from 100 Interviews

As our interview status recorded, I just have conducted 100 interviews at Facebook. I never did batch interviews (multiple interviews a day in consecutive days), so I’m feeling really excited about this accumulative achievement.
On this wonderful milestone, I’d like to share some of my experience and tips about being interviewer at Facebook, I hope you found this helpful.

Benefits as an Interviewer

There is no doubt that interviews are critical for company growth. However, I want to tell you more about the personal growth and benefits of being an Android interviewer.

  • Improving my verbal and written English
    Since English is my second language, interview is a great way for me to practice. I repeat similar conversation during interview, and this exposure increases my confidence in my speech; by providing post-interview feedback, I have increased the speed and quality of my writing.
  • Expanding my social network
    I felt so great when some colleagues suddenly stopped me and asked me “do you know you interviewed me?” then our conversation started very naturally (although, I’m really sorry, I didn’t actually remember the interview).
  • Business travel for recruiting events
    I got a chance to go back to my alma mater to give recruiting talk, which I previously never imagined. However, I also missed a couple trips to interview abroad due to my visa restriction.
  • Clarity on my work and teams
    Candidates often asked about my work and products at Facebook at the end of interviews. By thinking about and answering those questions, I clearly define my own duties, and the work of my team.
  • Polishing my technical skills and general Android knowledge
    The technical skills we use here are very Facebook specific, but I would hear a lot of different terminologies, libraries, architectures that are used by candidates. I can then follow up on these to keep up with the market.
  • Helping my friends apply for software engineer positions
    It’s fine to help friends to prepare for Facebook interviews, as long as we don’t leak the real questions we ask. So I can specifically tell my friends what interviews look like, and what skills they should focus on.
  • Better understand position and level requirements
    After seeing so many interview decisions, I get a better sense on the requirements for Android positions at each level. This also clarifies what gaps I need to fill to advance my own career.
  • Performance review and career growth
    To be honest, the number of interviews doesn’t play a key role on performance review at company. However all the benefits mentioned above helps me a lot on my growth.
2018-10-29
29 October
On October 29, 2018
In IT Products(数码产品), Mobile Development(移动开发), Tangential Speech(漫话杂谈)

Google Pixel 3 XL 用户体验

上周收到了Pixel 3 XL,简单上手使用之后,最直接的感受是比较失望:

  • 丑陋的刘海造型,而且特别的厚,大部分应用都还没有对其做适应,所以状态条看起来非常不协调
  • 背后的材料变成了玻璃的,没有了原来铝材料的质感好
  • 新的导航手势也不是很舒适,特别是上划两次才能打开应用列表,因为用上划一次来取代了最近使用应用列表
  • 扬声器非常的差,播放声音时背后震动很强烈,声音也闷得好像是老式收音机
  • 跟Pixel 2 XL相比没有特别大的提升

值得点赞的地方可能就是:相机拍摄的照片更加清晰了,特别是前置摄像头带了两个摄像头,拍人像更好看了;还有那 Nexus 系列就有的到了 Pixel 前两代却去掉了的无线充电功能。

对于刘海就特别想吐槽,这部分跟状态栏重叠,所以会导致能显示的通知消息比原来少,非常的讨厌。对于有些应用将状态栏改成其他颜色时,刘海就会特别明显,但是如果进行屏幕截图,刘海的黑色部分又会被自动补全,造成所见影像和生成的图片不一致,非常的抓狂。
要想去除刘海,就需要打开“开发者选项(Developers Options)”来设置,但是真缺了那状态栏的一点空间又觉得挺可惜的。最搞笑的是“Double Cutout”,对称的上下两个刘海,可惜截图是看不出来的。

应用方便,对于 Pixel 3 和 Pixel 3 XL 独享的 Screening Call 表示赞叹,可以过滤掉不少垃圾电话。有些不足的地方是翻译过来的文字必须当场阅读,电话挂断之后就会消失,如果能自动把内容转到Google Voice的留言信息保存起来就更好了。

另外,非常喜欢 Google 还在 beta 测试中的 Digital Wellbeing 的服务,可以看到每天在各种应用上浪费的时间。

同时设置时间来约束使用时长,当天的配额用完后,系统就会应用启动图标变灰并且不能再使用。比如我把 YouTube 的时间设置成了30分钟来防止自己沉迷,但实际是经常我就去设置那边把约束时间去掉,然后静静地在 YouTube 上度过了3个小时。所以本身的自制力才是关键。
希望以后这个服务可以推出更多功能,比如这些功能都是我希望其提供的:导出数据;家长约束并设置不同密码(这样就可以交给太太来管制我);桌面图标小插件;更方便的访问入口。

 

最后,放两张Pixel XL系列的照片(比较讽刺的是照片使用太太的 iPhone X 拍摄的),以及三款手机的规格对比。

Pixel 3 XL Pixel 2 XL Pixel XL
Height 158 mm (6.2 inches) 158 mm (6.2 inches) 154.7 mm (6 inches)
Width 76.7 mm (3.0 inches) 76.7 mm (3.0 inches) 75.7 mm (2.9 inches)
Thickness 7.9 mm (0.3 inches) 7.9 mm (0.3 inches) 8.5 mm (0.3 inches)
Weight 184 grams (6.49 ounces) 175 grams (6.2 ounces) 168 grams (5.93 ounces)
Screen Size 160 mm (6.3 inches) 152.4 mm (6.0 inches) 139.7 mm (5.5 inches)
Screen resolution 2,960 x 1,440 pixels 2,880 x 1,440 pixels 2,560 x 1,440 pixels
Pixel Density 523 ppi 538 ppi 534 ppi
Screen To Body Ratio 83.49% 76.71% 71.04%
RAM 4 GB 4 GB 4 GB
Storage space 64 GB, 128 GB 64 GB, 128GB 32 GB, 128 GB
Processor Qualcomm Snapdragon 845 Qualcomm Snapdragon 835 Qualcomm Snapdragon 821
Graphics Adreno 630 Adreno 540 Adreno 530
Camera 12MP rear, dual 8MP lenses front 12MP rear, 8MP front 12MP rear, 8MP front
Colors Just Black, Clearly White, Not Pink Just Black, Black and White Very Silver, Quite Black, Really Blue
Release date October 9, 2018 October 4, 2017 October 4, 2016
2018-09-24
24 September
On September 24, 2018
In Programming Life(程序人生), Tangential Speech(漫话杂谈)

我的四次Facebook面试经历

在 FB 已经工作了已经快三年了,在这段日子里我学到了很多也成长得很快,一切似乎都有序地推进着,可回过头看加入 FB 的过程却有些一波三折。翻看邮件记录,我总共面了 FB 四次:头两次面完后我被拒了,第三次拿到了Offer但换成我拒了他们,直到第四次才达成一致加入进来。

 

第一次面试是在研究生刚毕业的时候,那会儿社交网络正火,对于 FB 和 Twitter 这些比较热门的公司都会收到很多简历,所以对于New Grad来说申请的门槛却要高很多,我也尝试网上申请但都石沉大海。

后来是通过 Interviewstreet (网站现在已经更名为 HackerRank 了)这个在线程序测试平台才拿到了面试机会。当时 Interviewstreet 上的题库很小但难度很高,只要做完8道题就可以解锁网站上公司申请功能。我当时只是觉得在上边做题很有趣,就一直不停地钻研着,也要感谢一位学长在题目解法上给了我很多的指点让我更快地领悟了各种算法的真谛。在艰难地完成了8道题后,我就随便点了网站上包括 FB 在内的几个知名公司提交了申请,我也没有觉得会有下文只是继续在上边做题来努力提高排位。

在我去 Seattle 面试 Amazon 的路上,我收到了 Interviewstreet 给 FB recruiter的引荐邮件。这让我感到非常惊喜,立刻表达了我强烈的兴趣,然后顺利安排了电话面试。电面一共面了两题,第一题很快就解决了,但是第二道关于二分查找的变体我却卡在了条件检查上了,最后是通过电子邮件把最后的答案发了过去。在邮件里我还把我写二分法的博客链接贴了上去来表达我是懂这个算法,好在面试官给了我 onsite 的机会。

因为那时候在忙着毕业的事情,还要带家人在美国游玩,所以把面试安排到了一个月以后。也因为如此,我并没有能够充分地去准备面试。


Read More →

2017-08-28
28 August
On August 28, 2017
In Knowledge Base(心得笔库), Language Tips(语言初试), Software Engineering(软件工程)

Android单元测试有关资源

做Android开发,实在有太多的开源库和框架供开发者选用,总是让人无所适从到底哪个才是真正合适的。但是在自动化单元测试这一块,库的选择反而少了许多。可能是这些库实在太优秀了,也可能自动化测试的受重视程度相对较低所以没有太多人投入研发之中。

但是,自动化测试特别是单元测试(Unit Test)对于提高代码质量有很大的帮助。本文就来介绍一些Android中常用的单元测试库。

Junit

Junit是最主流的Java自动化则是框架,目前发展到Junit4。通过各种Java注解(Annotation)来标识测试的基本信息。
每个测试经历几个流程:设置,执行,验证。上手简单,运行快速,结果直观。API设计也很简洁,很容易扩展。

Mockito

单元测试最重要是减少测试对象的依赖,专注在该测试对象上。Mockito框架能很好的帮助我们完成这一目标,它在运行时将部分类在二进制层面替换掉,如此测试就不用依赖在实际代码上。
另外,单元测试中的断言验证(assertion)一般都是基于对象的状态(state),而Mockito提供了基于行为(behavior)的验证方式。

Robolectric

在Android的代码则很大程度依赖于Android的系统库,比如Context,View等等。其他几个库都是基于Java开发出来的,在单元测试中无法调用到Android系统的代码。Roboletric的出现就很好的解决了这个问题,它为测试提供了Android的系统代码, 并且通过配置可以指定运行的API等级。

AssertJ

JUnit自带assert方法来验证测试结果,这些方法使用了Hamcrest的函数式API。AssertJ则更具面向对象设计,并且是流式接口(fluent interface),让代码书写更加流畅,在IDE中也有更好的补全功能。
另外AssertJ扩展性也非常强,对于各种常用的Java库都有相应的扩展来更好的适应单元测试,比如Guava。即使是Android也有开源扩展库。
Read More →

Posts pagination

1 2 … 4 Next
Facebook
Twitter
LinkedIn
RSS
ZhiHu

Recent Posts

  • 三年居家工作感受
  • Pixel Watch智能手表和Pixel 5, 6 Pro 及 7 Pro手机
  • 我拥有过的无线耳机
  • 毕业工作一个月,我差点被开除
  • 我拥有过的移动硬盘
  • ProtoBuf 2.0 method count optimization for android development
  • 面过100场行为面试后

Categories

  • Algorithm Analysis(算法分析)
  • Article Collection(聚宝收藏)
  • Data Structures(数据结构)
  • Design Patterns(设计模式)
  • English Posts(英文写作)
  • Front Interface(界面构想)
  • IT Products(数码产品)
  • Knowledge Base(心得笔库)
  • Language Tips(语言初试)
  • Mathematical Theory(数学理论)
  • Mobile Development(移动开发)
  • Programming Life(程序人生)
  • Reading Notes(阅而后知)
  • Software Engineering(软件工程)
  • Special Tricks(奇技妙招)
  • Tangential Speech(漫话杂谈)

Tags

Aero Android API Bash Binary Search Bitwise Operation Book C/C++ Career Chrome Conference CSS Debug Device DOM Extension Framework Game Gradle Hearthstone HTML Initialization Intellij Interview iOS Java JavaScript jQuery Keyword Language Issues Mac Microsoft Mobile Modifier Objective-C PHP Principle Reference Regular Expression Static String Tools Tutorial UI XML

Blogroll

  • Ahmed's Blog
  • Gert Lombard's Blog
  • Gordon Luk
  • Jack & Allison
  • 开发部落

Archives

Designed using Chromatic. Powered by WordPress.