Android 静态变量优化

01.为啥不要用静态变量保存核心数据

  • 尽量不使用静态变量保存核心数据。这是为什么呢?
    • 这是因为android的进程并不是安全的,包括application对象以及静态变量在内的进程级别变量并不会一直呆着内存里面,因为它很有会被kill掉。
    • 当被kill掉之后,实际上app不会重新开始启动。Android系统会创建一个新的Application对象,然后启动上次用户离开时的activity以造成这个app从来没有被kill掉的假象。而这时候静态变量等数据由于进程已经被杀死而被初始化,所以就有了不推荐在静态变量(包括Application中保存全局数据静态数据)的观点。

02.实际开发中遇到的问题

  • 实际开发需求

    • 有一个倒计时抢红包活动页面,App端有一个轮训请求,大概每隔一分钟会请求一次服务器,用于更新用户的抢红包人数,还剩多少个红包,部分已抢红包的金额(弹出后消失)等信息。用户可以在当前页面停留很长的时间。需要注意的是这里还有一个抢红包按钮,点击这个按钮,用户开始并且跳转到抢红包【只是用于展示抢红包后的信息】页面,而这时候需要传递一个参数:用户的ID,此时用户的ID保存在了系统的静态变量中。请求接口成功后,将用户抢到的红包信息展现在该页面。
  • 出现的问题

    • 偶发性,请求接口时,服务端报异常,说请求时没有带有用户ID。但是App端的代码是判断此时的ID是否为空,若不为空的话则请求接口

      1
      2
      3
      if (!TextUtils.isEmpty(id)) {
      requestNet(id);
      }
  • 思考?

    • 这里的id是一个静态变量,而且没有手动的置空,为什么id会变为空了呢?
  • 还原出现bug的场景

    • 用户在某个时间段停留在当前形成页面;
    • 用户锁屏,系统限制后台网络请求,轮训操作被限制;
    • 系统内存吃紧,用户应用进程被杀死,进程的静态变量被初始化,activity界面被保留;
    • 用户打开屏幕,点击开始抢红包,这时候由于进程已经被杀死,静态变量被初始化,所以上报给服务器的id为空
    • 在用户打开屏幕的同时,系统重启应用进程,造成应用进程没有被杀死的假象;
  • 解决问题

    • 既然在内存中保存数据可能被系统杀死,那么可以有针对性的:
      • 使用官方推荐的几种方式将数据持久化到磁盘上。
      • 在使用数据的时候总是要对变量的值进行非空检查。
    • 使用sp存储和取出数据,在此种场景下是比较好的。