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

2021-12-21 11:44:24 +08:00
 Features
我在 Service 使用 Context.getAssets()
需要将 Activity.this 传入到 Service 中
因为 Activity 在退出程序后,就会 destroyed()
我担心传入 Service 的 Context 会跟随被销毁
但经过我监测,实际运行中并没有被销毁
这是什么原因呢?

这种情况是可靠的吗? Context 总是不会被销毁吗?
6043 次点击
所在节点    Android
26 条回复
winterbells
2021-12-21 12:09:33 +08:00
这个方法实际用的是 application context 吧
BigDogWang
2021-12-21 12:12:48 +08:00
这样会导致内存泄漏的,而且因为生命周期的问题 context 的一些方法会不能用
qwertasdf
2021-12-21 12:21:05 +08:00
因为你在 Service 里面正在持有这个 Context ,所以不会被摧毁,这就是经典的内存泄露吧。
Lin0936
2021-12-21 12:28:13 +08:00
Service 跟垃圾回收站打过招呼了,这个 Context 我要用,你先别回收
37927
2021-12-21 12:30:34 +08:00
Service 也是 Context 的子类,直接在 Service 里面使用 this.getAssets()就可以了,如果传入 Activity 的 Context ,关闭 Activity 后,Service 没有被销毁的话,会导致 Activity 不能被回收,造成内存泄露。
crayygy
2021-12-21 13:29:26 +08:00
memory leak
chengyiqun
2021-12-21 14:09:17 +08:00
@37927
@qwertasdf
如果直接使用全局静态的 Application 类获得 Context 可有问题?
leo7723
2021-12-21 14:32:04 +08:00
@chengyiqun 内存泄漏是一个相对的概念,对象再应该被回收的时候没有回收才叫内存泄漏。applicationcontext 的生命周期只会长于 service 所以不会有泄漏问题。
ProphetN
2021-12-21 14:36:32 +08:00
补充一下,如果要持有 Activity 的实例的话,都建议使用弱引用。
jinksw
2021-12-21 14:55:03 +08:00
你在 Service 使用 Context.getAssets()

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

这不是 Activity 生命周期的相关问题,而是 GC (垃圾回收)相关。当一个对象还存在引用时,虚机的垃圾回收机制就是不会回收这个对象。然后这就会导致此 Activity 在 Service 销毁前不会被销毁。也就是楼上说的内存泄露。
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
2021-12-21 17:04:09 +08:00
典型的内存泄漏。
Features
2021-12-21 18:27:46 +08:00
@jinksw 嗯嗯,我原来并不知道 Service 也继承自 Context ,然后我就把 activity 实例传给 Service 的 Presenter 类
现在改善了一下代码,把 Service 的实例传给 Presenter 类了。
Features
2021-12-21 18:35:47 +08:00
@loshine1992 谢谢,刚刚知道 Service 也继承自 Context😂
Features
2021-12-21 18:37:44 +08:00
@qwertasdf @Lin0936 @37927 @leo7723
有些问题想再请教下大家:
我做的是一个音乐播放器的 demo ,Service 在不断地更新播放器的 Seekbar ,也涉及到对 Seekbar 实例的调用
按理说应用到后台以后,Seekbar 实例就被销毁了,这时候是不是也会导致内存泄漏?
这个时候是不是应该放弃更新 Seekbar ?
DCELL
2021-12-21 19:47:22 +08:00
Service 不应该持有 Seekbar ;或者 Service 不应该去做 UI 更新,你应该通过观察者或者通知 去驱动 Activity 更新 UI 。
------ 一个 7 年前做过 android 开发的屌丝留,虽然不知道现在 android 技术已经更新到什么地步了,可能我的回答也是错的。
acidsweet
2021-12-21 20:34:31 +08:00
主要曲解了:Activity 的生命周期 vs Java 对象的生命周期
qwertasdf
2021-12-21 21:38:37 +08:00
@Features
你如果持有了,就会导致内存泄露,除非你在 Service 里面主动释放,否则你每次切换的时候都会有一个新的 Seebar 实例在 service 。
我年轻的时候应该是用广播来更改状态的,现在好像有 RxJava 之类的东西去更新状态
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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/823505

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX