Android 从服务中的活动访问变量的正确方法
在我的活动中,有一个变量(objectList),我希望从服务(TestService)访问该变量: 我的目标是每隔x秒从TestService循环遍历objectList中的每个项,处理一些数据,然后用新数据更新这个特定项Android 从服务中的活动访问变量的正确方法,android,android-activity,service,Android,Android Activity,Service,在我的活动中,有一个变量(objectList),我希望从服务(TestService)访问该变量: 我的目标是每隔x秒从TestService循环遍历objectList中的每个项,处理一些数据,然后用新数据更新这个特定项 MyObject类有很多属性需要更新。将objectList从mainActivity传递到TestService的正确方法是什么,这样我就可以直接使用objectList了?谢谢 通过在服务中维护对活动的引用,您引入了内存泄漏,因为当视图由于活动在其生命周期中的进展而被破
MyObject类有很多属性需要更新。将objectList从mainActivity传递到TestService的正确方法是什么,这样我就可以直接使用objectList了?谢谢 通过在
服务
中维护对活动
的引用,您引入了内存泄漏,因为当视图由于活动
在其生命周期中的进展而被破坏时,您可以防止系统对活动
进行垃圾收集
相反,您应该使用BroadcastReceiver
将服务
所做的更改传达给活动
,如@nongthonbamthoi在评论中所述。基本上,活动
应该实例化一个广播接收器
,该接收器在执行更新时侦听由服务
发送的特定类型的广播(由您定义的唯一键标识)
此外,我建议您移动列表,以便将其存储在
服务中,然后让活动通过绑定到服务,然后调用IBinder
实现中定义的方法,从服务中检索列表(应该从onBind(Intent)
返回其实例)。通过这种方式,您可以将对模型进行更改的所有代码限制在服务中,并将活动保持为一个(哑巴)只呈现模型的视图。更重要的是,使用此设计,您还可以通过启动服务(注意:除了绑定到它之外),使列表在活动期间更持久,这样即使活动被销毁,您也可以保留列表的状态(例如,由于您的申请被置于后台)。如果您选择此设计,服务发送的广播可以只是通知列表已更改,活动
然后可以通过调用IBinder
实现中指定的getList
方法检索更新的列表。您可以这样做,但不应访问活动直接从服务中获取变量,而应该使用BroadcastReceiver来更新列表(或UI)如果不是UI更新,请直接从服务加载列表或将列表传递到服务。非常感谢!快速提问,因为我正在从存储加载此列表,并且通过活动将新项目添加到列表中,所以我只需让服务从存储加载列表,对吗?此外,我正在将列表传递到RecyclerView.Adapter从活动中,我只需通过广播获取它,对吗?我不知道从服务广播中接收到的列表是“引用”还是“副本”?谢谢!请您更详细地解释这一步:“然后活动可以通过调用IBinder实现中指定的getList方法来检索更新的列表”这是否意味着我不会通过广播发送列表,而是该服务将具有活动可以访问的公共方法?谢谢!如果您决定在服务中返回对列表的引用或副本(甚至是列表的不可修改视图),则由您决定;所有这些都归结为您决定从IBinder
实现的getList
方法返回什么。我建议您看看《开发人员指南》中关于服务绑定的内容。简而言之,您从服务的onBind
返回IBinder
的实现。该实现应该ld定义一个方法,getList
,活动可以使用该方法检索列表。注意:您必须将返回的IBinder
转换为用户定义的类型。非常感谢您的时间和指导!
public class MainActivity extends AppCompatActivity
{
List<MyObject> objectList;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService( new Intent( getBaseContext(), TestService.class )
);
}
public class TestService extends Service
{
@Override
public IBinder onBind(Intent intent)
{
return null;
}
@Override
public void onCreate()
{
super.onCreate();
}
@Override
public int onStartCommand( Intent intent, int flags, int startId )
{
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy()
{
super.onDestroy();
}
}