Search code examples
javaandroidservice

How to access a variable of a service from an activity


I understand that in order to access methods of a service from an activity, we should bind the service.

But if we just want to get the value of a variable in the service, can we just access it like so without binding?

int myActivityVar = myService.myServiceVar;

It works, but I’m not sure if it has any memory leak implications or any other issues.


Solution

  • Solution

    • The Activity will send a BroadcastReceiver to the Service to request getting the data.

    • The Service will register the BroadcastReceiver, when receiving a broadcast message from the Activity, it will prepare result data and send it back to the Activity by using ResultReceiver.

    Implementation

    MyService.java

    public class MyService extends Service {
    
        public static final String ACTION_GET_DATA = "ACTION_GET_DATA";
        public static final String EXTRA_RECEIVER = "EXTRA_RECEIVER";
        public static final String EXTRA_DATA = "EXTRA_DATA";
    
        public static final int RESULT_OK = 1;
        public static final int RESULT_FAILED = 0;
    
        // The data of the Service that the Activity want to access.
        private int myServiceVar = 100;
    
        private final BroadcastReceiver onGetDataReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                // Send result data to the activity
                ResultReceiver receiver = intent.getParcelableExtra(EXTRA_RECEIVER);
                Bundle resultData = new Bundle();
                resultData.putInt(EXTRA_DATA, myServiceVar);
                receiver.send(RESULT_OK, resultData);
            }
        };
    
        @Override
        public void onCreate() {
            super.onCreate();
            registerReceiver(onGetDataReceiver, new IntentFilter(ACTION_GET_DATA));
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // TODO: Your code logic goes here.
            return Service.START_STICKY;
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    }
    

    MainActivity.java

    private void getDataFromService() {
        Handler mainHandler = new Handler(Looper.getMainLooper());
        ResultReceiver receiver = new ResultReceiver(mainHandler) {
            @Override
            protected void onReceiveResult(int resultCode, Bundle resultData) {
                if (resultCode == MyService.RESULT_OK) {
                    int data = resultData.getInt(MyService.EXTRA_DATA);
                    Log.i(TAG, "Received data = " + data);
                }
            }
        };
    
        Intent intent = new Intent(MyService.ACTION_GET_DATA);
        intent.putExtra(MyService.EXTRA_RECEIVER, receiver);
        sendBroadcast(intent);
    }