首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  Android

请教一个关于 android 静态变量的问题

  •  
  •   codechaser · 13 天前 · 870 次点击

    我有一个类,里面存储着一些 static 的变量,在整个程序中这些变量的值会变化,类似于这样:

    class Foo {
    	public static int FOO = 0;
    }
    

    这个 FOO 类里的变量 FOO 我会在 Service 里读取他,但是同时也有可能会被一些 activity 里的回调函数修改。service 有时候不能实时读取这个被修改的值,我现在的实现就是这样,让这个类可以被所有人访问修改,谁要用这个数值谁就去读,但是就像刚才说的,也许我想要的值会在我读取之后才被修改,造成了滞后。请问应该怎么解决呢?还是我这样的用法时大错特错的。

    21 回复  |  直到 2019-01-13 11:15:11 +08:00
        1
    11wangyaoda   13 天前
    关键词。atomic volatile concurrency.
        2
    ho121   13 天前 via Android
    可能 service 和 activity 没有在一个进程中
        3
    codechaser   13 天前 via Android
    @11wangyaoda 你好, 这个好像和原子性没啥关系吧?我这个变量在整个应用运行过程中都有可能被修改。
        4
    codechaser   13 天前 via Android
    @ho121 service 和 activity 都是同一个应用
        5
    guotao2beijing   13 天前
    应该不是滞后,你可以修改 F00 的值以后直接打印出来看看有没有修改。
    猜测是 service 在启动的时候就把 F00 的值持有在栈内存里了,而你改 F00 的值是改动堆内存里的数据,service 不知道。
        6
    symeonchen   13 天前 via Android
    取决于你的具体场景,不谈多进程的前提下,数据能被各处获取->单例 /持久化 /etc.;数据被操作的一段时间内禁止修改->加锁;数据的变化实时同步到各处->回调 /通知
        7
    ssynhtn   13 天前 via Android
    使用观察者模式:
    对于需要接收最新值的 service,subscribe 一下
    每次对这个值进行改动的时候,通知所有的 subscriber
        8
    Icezers   13 天前 via iPhone
    @codechaser 同一个应用不一定是同一个进程
        9
    frienmo   13 天前
    @Icezers 不好意思杠一下,应该是线程 thread 吧。同一个 app(jvm)了,一定是同一个进程 process 吧。
        10
    crayygy   13 天前 via iPhone
    @frienmo 不一定的,进程可以有多个,取决于实现,只是一般进程通信没有线程那么方便所以这么用的不多。
        11
    rosu   13 天前 via Android
    对值的读写顺序,应该只能通过程序逻辑来保证了。

    在语法方面应该不存在先修改,并且可多次修改后再读取。

    1. 要么像楼上那样,把这个变量用一个订阅改写成可订阅式,当被修改就通知订阅者( Service ),后者用标志变量来确认该值的修改状态?但是这样也不十分符合你的需求。也需要程序逻辑来保证。

    2. 如果是一次修改,之后不再对该变量执行写操作,可以用 kotlin 里的 by...lazy 来延迟初始化。
        12
    wolegequ   13 天前 via Android
    修改的时候打日志。btw 是通过 setter 修改的吗?
        13
    codechaser   13 天前 via Android
    @guotao2beijing 静态变量不是一直存在静态存储区吗?就是说我每次都得主动更新值是吗
        14
    ho121   13 天前 via Android
    @codechaser 简单的场景,service 改了值,然后进程被杀掉了,你再打开 activity,static 变量又被重新初始化一遍
        15
    codechaser   13 天前 via Android
    @ho121 是这样的,所以我现在只考虑应用运行过程中就行了😂
        16
    stuazt   13 天前
    LiveData/MutableLiveData 了解一下,官方 Android Architecture Components 的一个库。
        17
    brucewuio   13 天前
    重新学 java
        18
    codechaser   12 天前 via Android
    @brucewuio 学哪个部分?我马上去看
        19
    siyehua   12 天前
    @codechaser
    首先哪怕是同一个应用,也可以是不同的进程。
    其次,楼主表达的非常不清晰:到底是要每次去读 /写的时候,取的值一定是最新的,还是怎么样,从楼主题目上说的不是很清楚。
    然后,就算整个应用都可以访问,也可以做成私有的,然后使用方法来 get/set,这样无论是添加监听,或者是添加同步方法,都要容易得多。
    最后,如果这个变量有比较多的地方用到,且涉及到多线程 /进程,而且变化比较复杂。比如说这个值的写入,必须依赖其他地方的值(楼主说的滞后问题),那我建议使用同步方法修饰 set/get。如果写入不需要依赖,则可以使用 volatile
        20
    nicevar   10 天前
    @frienmo 同一个应用不一定是同一个进程,你在 service 的 process 属性里面配置 remote 就是在不同的进程了。这种情况是不能通过静态变量共享的。
    楼主的表达不够清晰,不过你的想法也是有点问题,你这种情形为什么不用 android 的 SharePreference 呢?很多人在使用静态变量的时候会犯两个错误,一个是不初始化,另一个就是跨进程访问。
        21
    codechaser   10 天前 via Android
    @nicevar 那些变量是随时要用的,所以我没考虑用 sharedpreference
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3744 人在线   最高记录 4236   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 19ms · UTC 06:56 · PVG 14:56 · LAX 22:56 · JFK 01:56
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1