Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android service-to-activity communication at high frequency: best option?

In an Android app (API level 14 and higher), which has a service used by different activities (they call its functions using a local binding), the service computes a position (coordinates) of a game-element at 60 Hz. [I have good reasons to do the computations in the service and not just in the activities directly]. These continuous position updates are required in the service (for game-logic checks) AND in the playscreen activities (for drawing).

My question to you is: what is the option to choose for service-to-activity communication for this scenario? I'd like to minimize the delay in milliseconds (at best, virtually no delay at all) between the point of time the service computed a fresh location, and the point when it is known to the UI (Activity).

You can assume that everything (activities, service) is in one process.

I was thinking about a solution where each activity, whenever it resumes, tells the service about its existence (and in onPause() the activities tell the service about their unavailability), so that the service, when it computed new coordinates, can simply check whether an activity is visible, and if it is, call visibleActivity.someMethod() directly. It is understood that .someMethod() internally hands control over to the UI thread.

I propose this, because I'm sure that going via Broadcasts should kill performance.

Let me know your thoughts!

like image 206
MShekow Avatar asked Oct 05 '22 17:10

MShekow


1 Answers

Your activities should register listeners implemented in AIDL with the service and the service should maintain them in a RemoteCallbackList

Your service should have two methods like this to be called by your Activities in onResume/onPause

public void registerListener(IYourListenerInterface listener) {
     callbackList.register(listener);
}


public void unregisterListener(IYourListenerInterface listener) {
     callbackList.unregister(listener);
}

When you need to send a message:

int numOfListeners = callbackList.beginBroadcast();

for (int i = 0; i < numOfListeners; i++) {
    try {
        callbackList.getBroadcastItem(i).whatever();
    } catch (RemoteException e) {
        //ignore, listener probably gone
    }
}
callbackList.finishBroadcast();
like image 116
Andy McSherry Avatar answered Oct 10 '22 04:10

Andy McSherry