当前位置: 首页 > 编程笔记 >

Android使用注解代替枚举节省系统内存开销的方法

令狐宏浚
2023-03-14
本文向大家介绍Android使用注解代替枚举节省系统内存开销的方法,包括了Android使用注解代替枚举节省系统内存开销的方法的使用技巧和注意事项,需要的朋友参考一下

Java5以后开始支持枚举类型,枚举类型使用起来非常方便,其重要的作用是作为类型安全使用的。如果在不考虑系统内存开销的情况下大量的使用枚举也不会有什么问题。但是移动端还是需要注意的。

android系统在应用启动后会给应用单独分配一块内存。应用的dex code、heap以及运行时的内存分配都会在这块内存中。而使用枚举类型的dex size是普通常亮的13倍以上。在运行时的内存分配,一个enum的声明至少要消耗掉20个bytes。从这两点就可以说明,在app中大量使用枚举的内存开销是非常大的。

枚举最大的优势是类型安全。那么是不是又办法在不使用枚举的情况下做到类型安全呢?答案是肯定的,下面看看怎么干。

goodle官方很早就发现了枚举对android系统带来的性能开销,所以在其官网上就已经提醒了开发者尽量少的使用枚举,而且还提供了注解的方式来检查类型安全。目前其提供了int和string两种注解方式。分别是:IntDef和StringDef。

话不多说,直接上例子。ps:demo里面有详细的注释。

一、Int类型注解检查类型安全

package com.yw.enumproxylib;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import androidx.annotation.IntDef;

/**
 * 定义一个int类型的注解
 * 用注解代替枚举,做到类型安全
 * create by yangwei
 * on 2020-01-30 21:34
 */
public class EnumProxy {
  public static final int READ_CAR = 0;//红色的汽车
  public static final int GREEN_CAR = 1;//绿色的汽车
  public static final int YELLOW_CAR = 2;//黄色的汽车


  @IntDef({READ_CAR, GREEN_CAR, YELLOW_CAR})
  @Retention(RetentionPolicy.SOURCE)//源码级别
  public @interface CAR_Enum {

  }

  /**
   * 获取汽车类型
   *
   * @param car
   * @return
   */
  public static int getCar(@CAR_Enum int car) {
    switch (car) {
      case READ_CAR:
        return 0;
      case GREEN_CAR:
        return 1;
      case YELLOW_CAR:
        return 2;
    }
    return -1;
  }
}

二、String类型注解检查类型安全

package com.yw.enumproxylib;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import androidx.annotation.StringDef;

/**
 * html" target="_blank">定义一个string类型的注解,用于检查星期的类型安全。
 * create by yangwei
 * on 2020-01-30 22:04 week
 */
public class StringEnum {

  public static final String MONDAY = "monday";
  public static final String TUESDAY = "tuesday";
  public static final String WENDESDAY = "wendesday";
  public static final String THURSDAY = "thursday";
  public static final String FRIDAY = "friday";
  public static final String SATURDAY = "saturday";
  public static final String WEEKDAY = "weekday";

  @StringDef({MONDAY, TUESDAY, WENDESDAY, THURSDAY, FRIDAY, SATURDAY, WEEKDAY})//此处定义注解的值只能是这几个
  @Retention(RetentionPolicy.SOURCE)//编译时注解,源码级检查
  public @interface Week {

  }

  /**
   * 获取日期
   *
   * @param week
   * @return
   */
  public static String getWeek(@Week String week) {
    switch (week) {
      case MONDAY:
        return "星期一";
      case TUESDAY:
        return "星期二";
      case WENDESDAY:
        return "星期三";
      case THURSDAY:
        return "星期四";
      case FRIDAY:
        return "星期五";
      case SATURDAY:
        return "星期六";
      case WEEKDAY:
        return "星期日";
    }
    return null;
  }
}

三、用来检查类型安全的MainActivity,从下面可以看到,当使用EnumProxy.getCar输入参数的时候,如果直接输入一个整数则编译不通过。当输入我们定义的EnumProxy.GREEN_CAR编译才通过。

同理StringEnum也能检查类型安全。

package com.yw.enumproxy;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import com.yw.enumproxylib.EnumProxy;
import com.yw.enumproxylib.StringEnum;

/**
 * 测试例子
 */
public class MainActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    int car_black = 10;
    int bk = EnumProxy.getCar(car_black);//此处类型检查不通过
    int ck = EnumProxy.getCar(EnumProxy.GREEN_CAR);//类型检查通过


    String str = "friday";
    String week1 = StringEnum.getWeek(str);//直接赋值String时类型检查不通过
    String week2 = StringEnum.getWeek(StringEnum.FRIDAY);//赋值定义好的值时类型检查通过
  }
}

以上知识点如果大家在学习的时候有任何疑问可以联系小牛知识库小编补充分享。

 类似资料:
  • 问题内容: 由于Java 1.4没有枚举,因此我正在执行以下操作: receiveSomeValue的调用者应传递这三个值之一,但他可以传递任何其他int值。如果它是一个枚举,则调用者只能传递一个有效值。 是否应该在receiveSomeValue中抛出InvalidValueException? 有哪些Java 5枚举的良好替代品? 问题答案: 在1.5版之前最好使用的是Typesafe枚举模式

  • 问题内容: 这不是卡住我的问题,而是我正在寻找一种编写代码的整洁方法。 本质上,我正在编写一个事件驱动的应用程序。用户触发一个事件,该事件被发送到适当的对象,然后这些对象处理事件。现在,我正在编写偶数处理程序方法,并且希望使用switch语句确定如何处理事件。现在,在我研究通用结构时,事件类非常简单: 然后,在另一堂课中,我会看到类似以下内容的内容: 我会 喜欢 做的就是这样的事情(尽管我当然会坚

  • 我刚刚开始研究系统调用。我想知道当进行系统调用时是什么导致了开销。 例如,如果我们考虑getpid(),当系统调用getpid()时,我的猜测是,如果控件当前位于子进程中,则必须进行上下文切换才能进入父进程以获取pid。这会导致间接费用吗? 此外,当调用getpid()时,会有一些元数据跨用户空间边界传输,并进入和退出内核。那么,用户空间和内核之间的不断切换也会导致一些开销吗?

  • 本文向大家介绍python使用__slots__让你的代码更加节省内存,包括了python使用__slots__让你的代码更加节省内存的使用技巧和注意事项,需要的朋友参考一下 前言 在默认情况下,Python的新类和旧类的实例都有一个字典来存储属性值。这对于那些没有实例属性的对象来说太浪费空间了,当需要创建大量实例的时候,这个问题变得尤为突出。 因此这种默认的做法可以通过在新式类中定义了一个__s

  • 问题内容: 我有一个枚举: 我想在Android注释的indDef中使用它: 错误显示: 找到不兼容的类型,必需:“ long” 这种不兼容该怎么办? 我不想手动处理AppEnum参数的值,Enum通常会自动创建值。返回enum参数的int值,但在这里不起作用。 问题答案: 注释的主要思想是使用常量集,例如an ,但 不使用 。在这种情况下,您必须手动声明所有常量。 您可以在此处查看详细的示例。

  • 本文向大家介绍Java的枚举类型使用方法详解,包括了Java的枚举类型使用方法详解的使用技巧和注意事项,需要的朋友参考一下 1.背景 在java语言中还没有引入枚举类型之前,表示枚举类型的常用模式是声明一组具有int常量。之前我们通常利用public final static 方法定义的代码如下,分别用1 表示春天,2表示夏天,3表示秋天,4表示冬天。 这种方法称作int枚举模式。可这种模式有什么