0x29a
0x29a

Reputation: 773

Proper way to access variable from activity within Service

In my activity, there's a variable (objectList) which I would like to access from a Service (TestService):

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 ) 
     );
}

And I have a skeleton for the Service:

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();
    }
}

My goal is to loop through every item in the objectList from the TestService every x seconds, process some data, and then update this particular item with new data.

The MyObject class has a lot of properties which I need to update. What is the proper way to pass the objectList from mainActivity to the TestService so I can work with the object list directly? Thanks!

Upvotes: 0

Views: 681

Answers (1)

Janus Varmarken
Janus Varmarken

Reputation: 2336

By maintaining a reference to an Activity in a Service, you introduce a memory leak since you prevent the system from garbage collecting the Activity when the view is destroyed as a result of the Activity progressing through its lifecycle.

Instead, you should communicate the changes made by the Service to the Activity using a BroadcastReceiver as explained by @NongthonbamTonthoi in the comment. Basically the Activity should instantiate a BroadcastReceiver that listens for a specific type of broadcasts (identified by a unique key defined by you) which are sent by the Service whenever it performs an update.

Furthermore, I suggest that you move the list so that it is stored in the Service and then make the Activity retrieve the list from the Service by binding to the Service and then invoking a method defined in your IBinder implementation (an instance of which should be returned from onBind(Intent)). This way you can confine all code that makes changes to your model to the Service and keep the Activity as a (dumb) view that simply renders the model. Morover, with this design, you can make your list outlast the Activity by also starting the Service (note: in addition to binding to it) so that you can retain the state of your list even if your Activity is destroyed (e.g., as a result of your application being put to the background). If you choose this design, the broadcast sent by the Service can simply be a notification that the list has changed, and the Activity can then retrieve the updated list by invoking the getList method specified in your IBinder implementation.

Upvotes: 1

Related Questions