初学 Android,请教下关于 context 的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Features
V2EX    Android

初学 Android,请教下关于 context 的问题

  •  
  •   Features 2021-12-21 11:44:24 +08:00 13692 次点击
    这是一个创建于 1439 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我在 Service 使用 Context.getAssets()
    需要将 Activity.this 传入到 Service 中
    因为 Activity 在退出程序后,就会 destroyed()
    我担心传入 Service 的 Context 会跟随被销毁
    但经过我监测,实际运行中并没有被销毁
    这是什么原因呢?

    这种情况是可靠的吗? Context 是不会被销毁吗?
    第 1 条附言    2021-12-21 18:30:35 +08:00
    有些问题想再请教下大家:
    我做的是一个音乐播放器的 demo ,Service 在不断地更新播放器的 Seekbar ,也涉及到对 Seekbar 实例的调用
    按理说应用到后台以后,Seekbar 实例就被销毁了,这时候是不是也会导致内存泄漏?
    第 2 条附言    2021-12-21 22:18:00 +08:00
    我看 Profiler 里,MyActivity 只是 stopped ,saved ,没有 destroyed
    这说明什么呢?
    我通过任务管理器杀死进程以后,Profiler 里的 MyActivity 才出现 destroyed
    26 条回复    2021-12-22 18:08:33 +08:00
    300
        1
    300  
       2021-12-21 12:09:33 +08:00 via Android
    这个方法实际用的是 application context 吧
    BigDogWang
        2
    BigDogWang  
       2021-12-21 12:12:48 +08:00
    这样会导致内存泄漏的,而且因为生命周期的问题 context 的一些方法会不能用
    qwertasdf
        3
    qwertasdf  
       2021-12-21 12:21:05 +08:00
    因为你在 Service 里面正在持有这个 Context ,所以不会被摧毁,这就是经典的内存泄露吧。
    Lin0936
        4
    Lin0936  
       2021-12-21 12:28:13 +08:00
    Service 跟垃圾回收站打过招呼了,这个 Context 我要用,你先别回收
    37927
        5
    37927  
       2021-12-21 12:30:34 +08:00
    Service 也是 Context 的子类,直接在 Service 里面使用 this.getAssets()就可以了,如果传入 Activity 的 Context ,关闭 Activity 后,Service 没有被销毁的话,会导致 Activity 不能被回收,造成内存泄露。
    crayygy
        6
    crayygy  
       2021-12-21 13:29:26 +08:00
    memory leak
    C02TobNClov1Dz56
        7
    C02TobNClov1Dz56  
       2021-12-21 14:09:17 +08:00
    @37927
    @qwertasdf
    如果直接使用全局静态的 Application 类获得 Context 可有问题?
    leo7723
        8
    leo7723  
       2021-12-21 14:32:04 +08:00
    @chengyiqun 内存泄漏是一个相对的概念,对象再应该被回收的时候没有回收才叫内存泄漏。applicationcontext 的生命周期只会长于 service 所以不会有泄漏问题。
    ProphetN
        9
    ProphetN  
       2021-12-21 14:36:32 +08:00
    补充一下,如果要持有 Activity 的实例的话,都建议使用弱引用。
    jinksw
        10
    jinksw  
       2021-12-21 14:55:03 +08:00
    你在 Service 使用 Context.getAssets()

    Service 也是 Context 呀 直接在 service 里调 this.getAssets()不就行了
    kop1989
        11
    kop1989  
       2021-12-21 15:03:03 +08:00
    你使用的 context 不会被销毁。

    这不是 Activity 生命周期的相关问题,而是 GC (垃圾回收)相关。当一个对象还存在引用时,虚机的垃圾回收机制就是不会回收这个对象。然后这就会导致此 Activity 在 Service 销毁前不会被销毁。也就是楼上说的内存泄露。
    loshine1992
        12
    loshine1992  
       2021-12-21 16:06:29 +08:00
    public abstract class Service extends ContextWrapper implements ComponentCallbacks2,
    ContentCaptureManager.ContentCaptureClient

    public class ContextWrapper extends Context

    ...
    ParfoisMeng
        13
    ParfoisMeng  
       2021-12-21 17:04:09 +08:00
    典型的内存泄漏。
    Features
        14
    Features  
    OP
       2021-12-21 18:27:46 +08:00
    @jinksw 嗯嗯,我原来并不知道 Service 也继承自 Context ,然后我就把 activity 实例传给 Service 的 Presenter 类
    现在改善了一下代码,把 Service 的实例传给 Presenter 类了。
    Features
        15
    Features  
    OP
       2021-12-21 18:35:47 +08:00
    @loshine1992 谢谢,刚刚知道 Service 也继承自 Context
    Features
        16
    Features  
    OP
       2021-12-21 18:37:44 +08:00
    @qwertasdf @Lin0936 @37927 @leo7723
    有些问题想再请教下大家:
    我做的是一个音乐播放器的 demo ,Service 在不断地更新播放器的 Seekbar ,也涉及到对 Seekbar 实例的调用
    按理说应用到后台以后,Seekbar 实例就被销毁了,这时候是不是也会导致内存泄漏?
    这个时候是不是应该放弃更新 Seekbar ?
    DCELL
        17
    DCELL  
       2021-12-21 19:47:22 +08:00
    Service 不应该持有 Seekbar ;或者 Service 不应该去做 UI 更新,你应该通过观察者或者通知 去驱动 Activity 更新 UI 。
    ------ 一个 7 年前做过 android 开发的丝留,虽然不知道现在 android 技术已经更新到什么地步了,可能我的回答也是错的。
    acidsweet
        18
    acidsweet  
       2021-12-21 20:34:31 +08:00
    主要曲解了:Activity 的生命周期 vs Java 对象的生命周期
    qwertasdf
        19
    qwertasdf  
       2021-12-21 21:38:37 +08:00
    @Features
    你如果持有了,就会导致内存泄露,除非你在 Service 里面主动释放,否则你每次切换的时候都会有一个新的 Seebar 实例在 service 。
    我年轻的时候应该是用广播来更改状态的,现在好像有 RxJava 之类的东西去更新状态
    john6lq
        20
    john6lq  
       2021-12-21 22:39:18 +08:00
    @Features 音乐播放器最简单了,正确的方式是 startService() 配合 bindService(),bind 成功拿到一个连接对象,通过它进行后续逻辑,多看看 GitHub 别人代码也就会了。
    https://developer.android.com/guide/components/bound-services?hl=zh-cn
    Lin0936
        21
    Lin0936  
       2021-12-22 09:35:52 +08:00   1
    @Features Service 去更新 UI 不是一个好的做法,现在推荐是通过 ViewModel 管理状态,然后 ViewModel 通知 Activity/Fragment 来更新
    zxjunz
        22
    zxjunz  
       2021-12-22 09:48:32 +08:00
    集美们,看到了吧,这就是典型的内存泄漏
    cenbiq
        23
    cenbiq  
       2021-12-22 10:42:18 +08:00
    @Features Service 持有 UI 对象本身就很离奇...楼上有给你推荐方法,说到底你需要的是某种通知机制,Service 在运行的时候能够“通知”UI 更新。
    lisongeee
        24
    lisongeee  
       2021-12-22 14:46:10 +08:00
    这里应该用广播或者 bind 做信息的传递吧
    Features
        25
    Features  
    OP
       2021-12-22 17:51:42 +08:00
    @lisongeee 是用的 Binder 传递,但是原理应该一样的吧?
    lisongeee
        26
    lisongeee  
       2021-12-22 18:08:33 +08:00
    @Features Binder 和 Broadcast 原理不一样
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2537 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 10:14 PVG 18:14 LAX 02:14 JFK 05:14
    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