Android 将活动引用传递给服务是否不好-不会造成任何问题
我试图从服务更新UI,我想将Android 将活动引用传递给服务是否不好-不会造成任何问题,android,Android,我试图从服务更新UI,我想将活动的引用传递给服务,如下所示: public class MainActivity extends AppCompatActivity{ ... onCreate(...){ //service already connected service.register(MainActivity.this); } } public class service extends Service(){ private MainActivity mA
活动的引用传递给服务,如下所示:
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();
}
}
创建的服务是一个已启动
和绑定
服务,因此即使在活动
被销毁后,它也会运行,因此我认为如果在活动被销毁后调用updateUI
方法,该服务会崩溃,但令我惊讶的是它没有崩溃。因此,我的第一个问题是,为什么即使UI组件不可用,服务也没有崩溃
当我重新获得UI时,我可能必须更新活动引用,但是,我想知道这种方法是否足够好,是否可以实现,许多人建议使用广播接收器
,但是如果这样可以,我真的希望使用它,而不是为了更新一个简单的组件而不得不经历更新UI的开销
编辑:我们将更新服务中的活动引用,如下所示:
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;
}
}
编辑2:还有,这个场景是内存泄漏吗?当活动被销毁时,服务
保存一个垃圾值(一个不可用的对象引用),但是当服务
被销毁时,内存被释放,对吗?所以,我认为这可能不是内存泄漏,但下面我们有一个讨论,它可能是,如果有人可以澄清这一点
为什么即使UI组件不可用,服务也没有崩溃
有空吗
由于您在服务
类中持有对main活动
的引用,垃圾收集器不会收集活动实例。这将导致应用程序内存泄漏
如果要确认该行为,请使用以下使用WeakReference
的服务类替换您的服务类。一旦MainActivity退出视图,下面的代码应该抛出一个NullPointerException
(假设MainActivity实例在该时间获得GC!)
公共类服务扩展服务(){
私有WeakReference mActivity=null;
公共无效登记册(主要活动){
mActivity=新的WeakReference(活动);
}
公共void updateUI(){
mActivity.get().getUI_组件().doSomething().update();
}
}
此外,我建议您看看,这是一个很好的库,可以帮助您调试常见的内存泄漏
当我重新获得活动时,我可能必须更新活动引用
用户界面
这取决于你到底想做什么。我假设您希望使用以前拥有的数据恢复UI。一种选择是使用保存信息的数据库或内存数据结构,并在创建信息后恢复UI状态。请提供有关您的特定用例的更多信息。是否真的需要MainActivity
参考,或者如果MainActivity实现UIComponentHolder
接口,是否需要例如UIComponentHolder
的参考?UIComponentHolder可以,但一旦MainActivity实现了接口,我们基本上还在传递活动的引用,对吗?它只是实现interfaceSame实例,但完全不同UIComponentHolder
实际上无法执行getContext()
或startActivityForResult
等等。。。但要回答你的问题——是的,这两件事都指向同一个例子;不,UIComponentHolder不是一个活动,但您要传递的实例(可能是MainActivity)也恰好是UIComponentHolder之外的一个活动。就泄漏而言,它很可能会泄漏,所以请确定您在服务中实际需要什么,并提供给它,而不是“一切”因此,服务可以从“一切”(在本例中为MainActivity)中获取所需的内容。WeakReference会有所帮助。LEakCannary虽然不错,但也会产生误报。尽可能不要在服务中保留活动引用。@Shark,服务也在单独的线程上执行,但UI更新只允许在主UI线程上进行,如何使用服务线程更新UI?即,我从服务线程调用活动的方法,这是怎么可能的?我确实想恢复UI状态,但在这种情况下,我正试图从服务中重新获得对UI的控制。“这将导致应用程序内存泄漏”,但它将如何导致内存泄漏?只要服务存在,活动就会一直存在,一旦服务被破坏,它就会消失,对吗?(因为,它是一个变量中的引用),最重要的是,如果我在方法中更新引用,比如onResume
,那么垃圾收集器应该收集以前的活动类,对吗?我正在考虑这个场景,您有活动A
和服务S
引用它。您导航到活动B
,并且A
中的所有视图都不会被使用,但它会保留在内存中,因为S
正在引用它。这就是内存泄漏的地方。没有完全遵循“更新onResume()中的引用”部分。如果数据不太占用内存,则可以使用一个singleton对象来保存数据。这样做的好处是你可以做DataHolder.save(…)
和DataHolder.restore()
之类的事情。你明白了!我认为这将是内存泄漏和上下文泄漏,但是-使用分析器。我所想的并不总是事情的现状。也一定要读到这篇文章
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();
}
}