首页 > 解决方案 > 将 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();
   }
}  

创建的服务是一个startedbound服务,因此即使在被销毁后它也会运行,所以我认为如果在活动被销毁后调用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,内存会被释放,对吧?所以,我认为这可能不是内存泄漏,但下面我们讨论它可能是,如果有人可以请澄清这一点。

标签: android

解决方案


为什么即使 UI 组件不可用,服务也不会崩溃?

由于您在类中持有对 的引用MainActivityService因此垃圾收集器不会收集活动实例。这将导致您的应用程序发生内存泄漏。

如果您想确认该行为,请将您的 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 状态。请提供有关您的特定用例的更多信息。


推荐阅读