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;

/**
 * 定义一个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);//赋值定义好的值时类型检查通过
  }
}

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

(0)

相关推荐

  • 自定义Android注解系列教程之注解变量

    前言 对于Android注解,或多或少都有一点接触,但相信大多数人都是在使用其它依赖库的时候接触的.因为有些库如果你想使用它就必须使用它所提供的注解.例如:ButterKnife.Dagger2.Room等等. 至于为何使用注解?使用过的应该都知道,最明显的就是方便.简洁.通过使用注解可以在项目编译阶段,帮助我们自动生成一些重复的代码,减轻我们的负担.典型的ButterKnife本质就是使用Android注解,通过注解来减少我们对view.findViewById的编写,提高我们的开发效率.上一

  • Android开发笔记之:用Enum(枚举类型)取代整数集的应用详解

    在Android的API中可以发现有很多用整数集来作为参数的地方,先来看一下实例.LinearLayout是大家所熟知的一个UI基本元素,它里面有一个方向的属性,可以通过以下方法来设置: 复制代码 代码如下: LinearLayout.setOrientation(int); 使用的时候,通常都是这样: 复制代码 代码如下: LinearLayout.setOrientation(LinearLayout.HORIZONTAL);LinearLayout.setOrientation(Linea

  • Android注解基础介绍快速入门与解读

    首先什么是注解?@Override就是注解,它的作用是: 1.检查是否正确的重写了父类中的方法. 2.标明代码,这是一个重写的方法. 1.体现在于:检查子类重写的方法名与参数类型是否正确:检查方法private/final/static等不能被重写.实际上@Override对于应用程序并没有实际影响,从它的源码中可以出来. 2.主要是表现出代码的可读性. 作为Android开发中熟知的注解,Override只是注解的一种体现,更多时候,注解还有以下作用: 降低项目的耦合度. 自动完成一些规律性的

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

    Java5以后开始支持枚举类型,枚举类型使用起来非常方便,其重要的作用是作为类型安全使用的.如果在不考虑系统内存开销的情况下大量的使用枚举也不会有什么问题.但是移动端还是需要注意的. android系统在应用启动后会给应用单独分配一块内存.应用的dex code.heap以及运行时的内存分配都会在这块内存中.而使用枚举类型的dex size是普通常亮的13倍以上.在运行时的内存分配,一个enum的声明至少要消耗掉20个bytes.从这两点就可以说明,在app中大量使用枚举的内存开销是非常大的.

  • Android使用Intent启动其他非系统应用程序的方法

    本文实例讲述了Android使用Intent启动其他非系统应用程序的方法.分享给大家供大家参考,具体如下: android应用程序内部通过Intent来实现Activity间的跳转.也知道通过Intent调用系统程序.但若想在应用程序A内开启应用程序B(前提是A.B均已安装),该如何去实现? 记录下实现过程. 在应用程序A内添加如下代码: Intent i = new Intent(); i.setClassName("com.example.a", "com.example

  • Android 异步获取网络图片并处理导致内存溢出问题解决方法

    测试环境为Adnroid 2.1以上. 1.AndroidManifest.xml 权限配置: 添加互联网访问权限: 复制代码 代码如下: <uses-permission android:name="android.permission.INTERNET" /> 2.异步图片类 ImageDownloadTask 复制代码 代码如下: import java.io.ByteArrayOutputStream; import java.io.IOException; imp

  • 用Python中的__slots__缓存资源以节省内存开销的方法

    我们曾经提到,Oyster.com的Python web服务器怎样利用一个巨大的Python dicts(hash table),缓存大量的静态资源.我们最近在Image类中,用仅仅一行__slots__代码,让每个6G内存占用的服务进程(共4个),省出超过2G来. 这是其中一个服务器在部署代码前后的截图: 我们alloc了大约一百万个类似如下class的实例:   class Image(object):     def __init__(self, id, caption, url):   

  • Android获取系统储存以及内存信息的方法(二)

    Android获取储存信息以及内存信息可以用adb命令查看. adb查看系统内存信息以及储存信息: 命令:adb shell cat /proc/meminfo 代码: private static final String FILENAME_PROC_MEMINFO = "/proc/meminfo"; /** * 获取手机内存总大小 * @return */ public static String getTotalMemorySize() { try { FileReader f

  • Android获取系统储存以及内存信息的方法(一)

    众所周知,Android的手机上的信息大部分都是可以通过代码获取的,比如说爱奇艺的离线储存功能上有一个最大储存大小/剩余储存大小的功能. 获取SD卡上的储存信息: /** * 获得SD卡总大小 * * @return */ private String getSDTotalSize() { File path = Environment.getExternalStorageDirectory(); StatFs stat = new StatFs(path.getPath()); long bl

  • Android编程实现获取系统内存、CPU使用率及状态栏高度的方法示例

    本文实例讲述了Android编程实现获取系统内存.CPU使用率及状态栏高度的方法.分享给大家供大家参考,具体如下: DeviceInfoManage类用于获取系统的内存,CPU的信息,以及状态栏的高度 import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReade

  • Android Bitmap详解及Bitmap的内存优化

    Android Bitmap详解及Bitmap的内存优化 一.Bitmap: Bitmap是Android系统中的图像处理的最重要类之一.用它可以获取图像文件信息,进行图像剪切.旋转.缩放等操作,并可以指定格式保存图像文件. 常用方法: public void recycle() // 回收位图占用的内存空间,把位图标记为Dead public final boolean isRecycled() //判断位图内存是否已释放 public final int getWidth() //获取位图的

  • Android使用注解进行代码检查的实现方法

    Android Studio 内置了代码检查工具 Lint,可在菜单栏选择 Analyze > Inspect Code 执行相应的代码检查,代码检查能够根据推断一些不合法的潜在问题,有助于在开发阶段发现开发者因为主管原因导致的一下代码问题,Android 官方提供了注解库 support-annotations 来帮助开发者及早发现问题,下面是常用的一些注解,主要内容如下: Nullness注解 资源注解 线程注解 值约束注解 权限注解 返回值注解 CallSuper注解 Typedef注解

  • Android加载图片内存溢出问题解决方法

    1. 在Android软件开发过程中,图片处理是经常遇到的. 在将图片转换成Bitmap的时候,由于图片的大小不一样,当遇到很大的图片的时候会出现超出内存的问题,为了解决这个问题Android API提供了BitmapFactory.Options这个类. 2. 由于Android对图片使用内存有限制,若是加载几兆的大图片便内存溢出.Bitmap会将图片的所有像素(即长x宽)加载到内存中,如果图片分辨率过大,会直接导致内存OOM,只有在BitmapFactory加载图片时使用BitmapFact

随机推荐