Search code examples
androidperformanceandroid-serviceandroid-broadcast

Best way to communicate a service with an activity (broadcast, callbacks, etc)


What I have:

I have a library running on a process using aidl. I have an app that uses this library, and on the messaging activity, I connect with the service to send messaging and I have a broadcast receiver to manage the incoming messages.

The problem?

if this library are going to be used by two apps on the same device the broadcast actions are going to be the same, and I will have problems when I send a broadcast.

What is my doubt?

What is the best way to "listen" the new incoming messages that I receive on my library and send it to the App. Maybe a callback? or there are any better solution?

More information

The library provides a few methods to start a session, and other methods for send different type of messages (images, text, locations, etc...) and I receive a callback from another library, that uses C and C++, when a new message is incoming.

If you need more information feel free to ask.

My Code:

IRemote.aidl

interface IRemote
{
    int sendTextMessage(String to, String message); 
}

WrapperLibrary.java

public class MyLibrary extends Service {

    // Current context, used to sendbroadcast() from @Callbacks 
    private Context mContext = this;

    private static MyLibrary instance = new MyLibrary();

    //Executor to start a new thread from the service.
    final ExecutorService service;

    @Override
    public IBinder onBind(Intent arg0) {
        //Return the interface.
        return mBinder;
    }

    /** Return the current instance */
    public static WrapperLibrary getInstance() {
        return instance;
    }

private final IRemote.Stub mBinder = new IRemote.Stub() {

        @Override
        public int sendTextMessage(String to, String message)
                throws RemoteException {


            Log.d(TAG, "Send Text Message. ");
            int i = -1;
            Future<Integer> task;
            task = service.submit(new Callable<Integer>() {
                public Integer call() {
                    return tu.tu_message_send_text(to, message);
                }
            });
            try {
                i = task.get();
            } catch (Exception e) {
                Log.e(TAG, "Send Text Message: EXCEPTION *** " + e.getMessage());
            }

            Log.d(TAG, "Send Text Message: Status Code: " + i);

            return 0;
        }

}

Callbacks.java

public class Callbacks extends JNICallback {

    private Context mContext;


    public Callbacks(Context context) {
        this.mContext = context;
    }

    public void on_incoming_text_message(final String from, final String message) {

        Log.d(TAG, " Incoming TEXT message from:" + from + " with message: " + message);
        Intent i = new Intent(BroadcastActions.INCOMING_TEXT_MESSAGE);
        i.putExtra("from", from);
        i.putExtra("message", message);
        mContext.sendBroadcast(i);

    }

}

MainActivity.java On this activity I have a broadcast receiver and I can update the UI with a new message

    public class MessageReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {

            Bundle extra = intent.getExtras();
            String incomingMessage = "";

            if(extra != null) {

                incomingMessage = extra.getString("message");
                addNewMessage(new Message(incomingMessage, false));
            }

            Toast.makeText(MessagingActivity.this, "Incoming Message", Toast.LENGTH_LONG).show();

        }

    };

Solution

  • Well, finally I will use a Callbacks implementation. The architecture is going to be like this:

    App

    • Main Activity (Connect with the LibService)
    • LibService (is going to have the callbacks and broadcast receivers)

    Library

    • Callbacks and interfaces but not running in a service.

    This is the best approach to me to the future integration on other projects, and the library is going to be more simple without aidl and services.

    I thought the use of the receivers was a very good options, but thinking about the integration on other projects this is the best way to do it (for me).