怎样用 Android Annotations 写出高性能代码

简介: 上一篇博文中简单介绍了 Android Annotations 的基本用法,顺便扯了一下概念 - 契约编程,阅读量少的可怜,看来并没有多少人对此感兴趣,今天再来一篇,介绍几个稍微高级点的用法,我就不信弄不出一个大新闻。 本篇将要介绍的几个也许并不常用,但是逼格是有保证的,它们是 Thread A

上一篇博文中简单介绍了 Android Annotations 的基本用法,顺便扯了一下概念 - 契约编程,阅读量少的可怜,看来并没有多少人对此感兴趣,今天再来一篇,介绍几个稍微高级点的用法,我就不信弄不出一个大新闻。

本篇将要介绍的几个也许并不常用,但是逼格是有保证的,它们是

  • Thread Annotations
  • CheckResult Annotations
  • CallSuper Annotations
  • Enumerated Annotations

Thread Annotations

Thread Annotations 有四位成员 - @UiThread@MainThread@WorkerThread@BinderThread,它们来自不同的 java 文件,却拥有着共同的 target,不信你看:

@Retention(CLASS)
@Target({METHOD,CONSTRUCTOR,TYPE})
  • 1
  • 2

如果标记 class,那么这个 class 的所有方法都必须在指定线程上执行,例如

@UiThread
public class NavigationBar {
  @NonNull
  private NavigationBar addEntry(
    @StringRes int iconFontRes, 
    @NonNull String title,
    @NonNull OnClickListener listener) {
    // ...
  }
  // ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这样一来,NavigationBar 的所有方法都要运行在 Ui Thread,否则 Android Studio 会!报!错!

@MainThread 与 @UiThread 的区别比较微妙,首先放放链接 - Support Annotations。总结起来一句话:@MainThread 用于标记与生命周期相关的方法,@UiThread 用于 View Hierarchy,但是 Android Studio 认为两者是可以互换的,所以有这两种标记的方法可以互相调用。

然后我再稍微补充几句:

一个进程有且只有一个主线程 - @MainThread,同时它也是一个 @UiThread。例如,activity 的 main window 就运行在 @MainThread 上,但是系统也允许应用创建其他的线程以运行不同的 window(除了系统进程会这么干,几乎没有其他场景)

@CheckResult

这个 Annotation 对于【只看方法名无法判断是否有返回值】的方法特别管用,例如:

public boolean openUp()
  • 1

只看方法名openUp,可能不会多想,调用一下就完事了,也不会判断返回值。 
但是如果必须要判断 openUp 的返回值,除了文档约束好像也没有其他办法,有了 @CheckResults,一切都变得简单明了。

check result

@CallSuper

如果你提供了 api 给别人用,但是这个 api 必须要先调用父类方法才能正确执行,怎么办?让 @CallSuper 来拯救你。

CallSuper

Enumerated Annotations

编写高性能代码,从不用 enum 开始!

每一个 enum 都是一个对象,无论从内存还是从性能上来看,都没有一个 primitive type 的变量效率高。

例如,定义一个类 - ActionBar,用户可以通过 setMode 设置不同的模式,如果使用 enum,可能会写成下面这样:

public class ActionBar {
    public enum Theme {
        DARK, LIGHT
    }
    private Theme mTheme;
    public void setTheme(Theme theme) {
        mTheme = theme;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

为了提升代码效率,可以用两个整形变量来替代 Theme,但是这样无法保证参数 theme 的合法性,用户可能传入了 DARK 和 LIGHT 之外的值。

public class ActionBar {
    public static final int DARK = 0x00;
    public static final int LIGHT = 0x01;

    private int mTheme;

    public void setTheme(int theme) {
        mTheme = theme;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

如何既能提升效率又可以保证传入参数的合法性呢? 
用 @IntDef 来添加一个约束就搞定了。

public class ActionBar {

    @IntDef({DARK, LIGHT})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Theme {}

    public static final int DARK = 0x00;
    public static final int LIGHT = 0x01;

    private int mTheme;

    public void setTheme(@Theme int theme) {
        mTheme = theme;
    }

    @Theme
    public int getTheme() {
        return mTheme;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

如果用户调用 setTheme 时传入了非法参数,Android Studio 会!报!错!

IntDef

如果我们打算把 DARK 和 LIGHT 作为一个 flag,允许用户通过逻辑运算去自由组合,也就说可以这样调用 setTheme

setTheme(DARK | LIGHT);
setTheme(DARK & LIGHT);
  • 1
  • 2

只需要把 @IntDef 的 flag 属性设为 true 即可。

public class ActionBar {

    @IntDef(flag = true, value = {DARK, LIGHT})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Theme {}

    public static final int DARK = 0x00;
    public static final int LIGHT = 0x01;

    private int mTheme;

    public void setTheme(@Theme int theme) {
        mTheme = theme;
    }

    @Theme
    public int getTheme() {
        return mTheme;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

@StringDef 与 @IntDef 的原理一样,只不过用到的常量是 String 类型。

参考资料

转自: 一介码农
目录
相关文章
|
1月前
|
Ubuntu 网络协议 Java
【Android平板编程】远程Ubuntu服务器code-server编程写代码
【Android平板编程】远程Ubuntu服务器code-server编程写代码
|
1月前
|
数据库 Android开发 开发者
构建高性能微服务架构:从理论到实践构建高效Android应用:探究Kotlin协程的优势
【2月更文挑战第16天】 在当今快速迭代和竞争激烈的软件市场中,微服务架构以其灵活性、可扩展性和独立部署能力而受到企业的青睐。本文将深入探讨如何构建一个高性能的微服务系统,涵盖从理论基础到具体实现的各个方面。我们将重点讨论服务拆分策略、通信机制、数据一致性以及性能优化等关键主题,为读者提供一个清晰、实用的指南,以便在复杂多变的业务环境中构建和维护健壮的微服务体系结构。 【2月更文挑战第16天】 在移动开发领域,性能优化和流畅的用户体验是至关重要的。随着技术的不断进步,Kotlin作为一种现代编程语言,在Android开发中被广泛采用,尤其是其协程特性为异步编程带来了革命性的改进。本文旨在深入
238 5
|
3月前
|
人工智能 IDE 开发工具
Studio Bot - 让 AI 帮我写 Android 代码
Studio Bot - 让 AI 帮我写 Android 代码
150 1
|
9月前
|
IDE 数据可视化 Java
Android自动生成代码,可视化脚手架之基础信息配置
今天的内容比较简单,大致过一下Electron一些基本用法,虽然说这些比较简单,但又是不得不去了解的,正如做Android的我们,也不是一上来就会的,需要一个循序渐进的过程,下一章,我们再去实际的开发功能。
127 0
|
2月前
|
Ubuntu 网络协议 Linux
【Linux】Android平板上远程连接Ubuntu服务器code-server进行代码开发
【Linux】Android平板上远程连接Ubuntu服务器code-server进行代码开发
47 0
|
3月前
|
安全 算法 JavaScript
安卓逆向 -- 关键代码定位与分析技术
安卓逆向 -- 关键代码定位与分析技术
36 0
|
3月前
|
安全 Android开发 数据安全/隐私保护
代码安全之代码混淆及加固(Android)
代码安全之代码混淆及加固(Android)
40 0
|
4月前
|
安全 Java Android开发
Android App开发之安全加固中反编译、代码混淆、第三方加固以及重签名的讲解及实战(图文解释 简单易懂)
Android App开发之安全加固中反编译、代码混淆、第三方加固以及重签名的讲解及实战(图文解释 简单易懂)
70 0
|
6月前
|
XML Java Android开发
Android 解决使用CocosCreator开发产品上架应用市场代码重复问题
Android 解决使用CocosCreator开发产品上架应用市场代码重复问题
270 0
|
7月前
|
JSON dexposed Java
一文总结 Android 隐私合规代码思路
一文总结 Android 隐私合规代码思路