android - 将 Activity 的引用传递给服务是否不好-不会造成任何麻烦
问题描述
我试图从服务更新 UI,我想将引用传递Activity
给服务,如下所示:
public class MainActivity extends AppCompatActivity{
... onCreate(...){
//service already connected
service.register(MainActivity.this);
}
}
public class service extends Service(){
private MainActivity mActivity = null;
public void register(MainActivity activity){
mActivity = activity;
}
public void updateUI(){
mActivity.getUI_Component().doSomething().update();
}
}
创建的服务是一个started
和bound
服务,因此即使在被销毁后它也会运行,所以我认为如果在活动被销毁后调用Activity
该方法,服务会崩溃,但令我惊讶的是它没有崩溃。所以,我的第一个问题是,为什么即使 UI 组件不可用,服务也没有崩溃。updateUI
当我重新获得 UI 时,我可能必须更新活动参考,但是,我想知道这种方法是否足够好来实现,许多人建议使用它Broadcast Receiver
,但如果可以,我真的想使用这而不必通过更新 UI 来更新简单组件的开销
编辑:我们会像这样更新服务中的 Activity 引用:
public class MainActivity ...{
@Override
public void onResume(){
service.re_register(MainActivity.this);
}
}
public class service extends Service(){
private MainActivity mActivity;
...
public void re_register(MainActivity newActivity){
mActivity = newActivity;
}
}
EDIT2:另外,这个场景是内存泄漏吗?当 Activity 被销毁时,它会Service
保存一个垃圾值(一个不可用的对象引用),但是当 Activity 被销毁时Service
,内存会被释放,对吧?所以,我认为这可能不是内存泄漏,但下面我们讨论它可能是,如果有人可以请澄清这一点。
解决方案
为什么即使 UI 组件不可用,服务也不会崩溃?
由于您在类中持有对 的引用MainActivity
,Service
因此垃圾收集器不会收集活动实例。这将导致您的应用程序发生内存泄漏。
如果您想确认该行为,请将您的 Service 类替换为以下使用WeakReference<MainActivity>
. NullPointerException
一旦 MainActivity 离开视图,下面的代码应该抛出一个(假设 MainActivity 实例到时候得到 GC!)。
public class service extends Service(){
private WeakReference<MainActivity> mActivity = null;
public void register(MainActivity activity){
mActivity = new WeakReference(activity);
}
public void updateUI(){
mActivity.get().getUI_Component().doSomething().update();
}
}
此外,我建议您看一下LeakCanary,这是一个很好的库,可以帮助您调试常见的内存泄漏。
当我重新获得 UI 时,我可能不得不更新活动参考
这取决于你到底想做什么。我假设您想使用以前拥有的数据来恢复 UI。一种选择是使用数据库或内存数据结构来保存信息,并在创建后恢复 UI 状态。请提供有关您的特定用例的更多信息。
推荐阅读
- realm - 怎么可能在 Realm 上从 SQLite 执行相当于 onUpgrade() 的操作?
- javascript - 如何仅使用 Javacript 中的加速度值计算位移值?
- typescript - 如何推迟打字稿中的通用填充 - 用于 knex 查询?
- pygame - python - 为什么玩家在pygame中与敌人发生碰撞时我的游戏一直冻结
- javascript - Cypress 中的 Onload() 函数
- installation - 如何使用 CMake 安装依赖库?
- swift - 当您观察该密钥时,是否也下载了父密钥?
- django - /BRMapp/view-books/ 处的 AttributeError
- regex - 正则表达式:非贪婪搜索
- r - R 中的 For 循环 - 更改每月回报的序列