请教一个关于 android 静态变量的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
codechaser
V2EX    Android

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

  •  
  •   codechaser 2019-01-09 17:36:15 +08:00 12486 次点击
    这是一个创建于 2516 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    class Foo { public static int FOO = 0; } 

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

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

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

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

    2. 如果是一次修改,之后不再对该变量执行写操作,可以用 kotlin 里的 by...lazy 来延迟初始化。
    wolegequ
        12
    wolegequ  
       2019-01-10 00:42:44 +08:00 via Android
    修改的时候打日志。btw 是通过 setter 修改的吗?
    codechaser
        13
    codechaser  
    OP
       2019-01-10 08:31:47 +08:00 via Android
    @guotao2beijing 静态变量不是一直存在静态存储区吗?就是说我每次都得主动更新值是吗
    ho121
        14
    ho121  
       2019-01-10 09:13:56 +08:00 via Android
    @codechaser 简单的场景,service 改了值,然后进程被杀掉了,你再打开 activity,static 变量又被重新初始化一遍
    codechaser
        15
    codechaser  
    OP
       2019-01-10 09:19:42 +08:00 via Android
    @ho121 是这样的,所以我现在只考虑应用运行过程中就行了
    stuazt
        16
    stuazt  
       2019-01-10 10:18:47 +08:00
    LiveData/MutableLiveData 了解一下,官方 Android Architecture Components 的一个库。
    brucewuio
        17
    brucewuio  
       2019-01-10 14:06:32 +08:00
    重新学 java
    codechaser
        18
    codechaser  
    OP
       2019-01-10 15:40:54 +08:00 via Android
    @brucewuio 学哪个部分?我马上去看
    siyehua
        19
    siyehua  
       2019-01-10 22:31:41 +08:00
    @codechaser
    首先哪怕是同一个应用,也可以是不同的进程。
    其次,楼主表达的非常不清晰:到底是要每次去读 /写的时候,取的值一定是最新的,还是怎么样,从楼主题目上说的不是很清楚。
    然后,就算整个应用都可以访问,也可以做成私有的,然后使用方法来 get/set,这样无论是添加监听,或者是添加同步方法,都要容易得多。
    最后,如果这个变量有比较多的地方用到,且涉及到多线程 /进程,而且变化比较复杂。比如说这个值的写入,必须依赖其他地方的值(楼主说的滞后问题),那我建议使用同步方法修饰 set/get。如果写入不需要依赖,则可以使用 volatile
    nicevar
        20
    nicevar  
       2019-01-13 11:12:53 +08:00
    @frienmo 同一个应用不一定是同一个进程,你在 service 的 process 属性里面配置 remote 就是在不同的进程了。这种情况是不能通过静态变量共享的。
    楼主的表达不够清晰,不过你的想法也是有点问题,你这种情形为什么不用 android 的 SharePreference 呢?很多人在使用静态变量的时候会犯两个错误,一个是不初始化,另一个就是跨进程访问。
    codechaser
        21
    codechaser  
    OP
       2019-01-13 11:15:11 +08:00 via Android
    @nicevar 那些变量是随时要用的,所以我没考虑用 sharedpreference
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     867 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 22:40 PVG 06:40 LAX 14:40 JFK 17:40
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86