1

I'd like to implement two-way communication between my Activity and an IntentService via Messaging.

In this Google sample project the Handler class is implemented as an inner class in the Activity:

class IncomingHandler extends Handler {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case MessengerService.MSG_SET_VALUE:
                mCallbackText.setText("Received from service: " + msg.arg1);
                break;
            default:
                super.handleMessage(msg);
        }
    }
}

Implementing my Handler in the same manner results in the following warning:

This Handler class should be static or leaks might occur

So after checking out this answer, i've implemented mine as a static nested class, something like this:

private static class IncomingHandler extends Handler {

    private final WeakReference<MainActivity> mainActivity;

    IncomingHandler(MainActivity activity) {
        mainActivity = new WeakReference<MainActivity>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        MainActivity activity = mainActivity.get();
        if(activity != null) {
            activity.doStuff();
        }
    }
}

Is this a safe approach to handle the warning above?

Thanks in advance.

Community
  • 1
  • 1
justanoob
  • 1,797
  • 11
  • 27
  • 1
    you can ignore that warning at all: it is only valid if messages are sent with a "delay" which is not case for `Messenger`, btw if your activity and service are hosted by the same process you can just use "bound local service" pattern, no need for `Messenger` or such – pskink Aug 28 '16 at 08:59
  • @pskink Thanks for your comment. Is it possible to implement two-way communication with the bound local service pattern? As i understand i can call methods of my Service that way, but i cannot call methods of my Activity from my Service without using a Messenger. – justanoob Aug 28 '16 at 09:03
  • let your activity just call "register" method with a callback interface as a parameter, and then your service can use that interface when calling back activity – pskink Aug 28 '16 at 09:09
  • If my Activity implements that interface and i pass the Activity instance to the Service, wouldn't it cause a memory leak on an orientation change, and make my Service to call back to the "destroyed" Activity? – justanoob Aug 28 '16 at 09:23
  • 1
    so the procedure is as follows: you call `bindService` inside `Activity#onCreate`, inside `onServiceConnected` you call "register" method with your iface and inside `Activity#onDestroy` you first call "unregister" method followed by `unbindService` – pskink Aug 28 '16 at 09:39
  • Sounds good, thank you. – justanoob Aug 28 '16 at 09:58
  • and on the service side you can use `WeakHashMap` or similar things in order to be sure you are not hard referencing your clients – pskink Aug 28 '16 at 17:52

0 Answers0