Tuesday, June 26, 2018

Best way to communicate between two applications

Leave a Comment

I want to create a central application for a suite of applications. The suite of applications are developed by ourselves and third party vendor. We would like to know the best approach to achieve below features

1) Launch the sub application from the central application

The sub applications are installed in the device and package name of sub applications are provided by the vendors.We thought of using explicit intent to invoke the sub application. Any other approach to start the sub applications from central application.

2) Communication between the central and sub Applications.

There is no communication layer for the sub applications. Every communication from the sub applications should be send to server via central application. The communication includes GET, POST, PUT request. We thought of using Broad cast receivers to send the payload to central application. The central application will in turn send the payload to server. But Broadcast receiver restrictions on Android Oreo will make this solution not viable.

3) close sub applications launched from central application when user performs log out in central app.

We are thinking to use killBackgroundProcesses() API provided as part of ActivityManager to kill the process. Any other solution to kill the process ? Any negative impacts in using this API to kill the process ?

4) Publish of events from central application to sub applications to consume.

We thought of broadcast receiver to publish the events from central to sub applications. But as mentioned above Broadcast receiver restrictions on Android Oreo will make this solution not viable. Any alternative solution ?

4 Answers

Answers 1

What you need is Implicit Intents. This way your sub-applications do not need to know implementation details from your central application.

Just create an intent, using a specific action constant that your central application will understand as a command. The central application then decides what REST operation to complete. (I would recommend each of your sub and central applications includes the same library module (effectively an SDK) which will contain the constants)

 //in this example ActionConstants would just be a class with  //some string constants  Intent intent = new Intent(ActionConstants.UPDATE_NAME);  intent.putExtra(ActionConstants.EXTRA_NAME, myNewName);   public final class ActionConstants {       public static final String UPDATE_NAME = "com.my.example.app.UPDATE_NAME";       private ActionConstants(){}   } 

Your applications presumably are separate APK's which means you may want to check whether the Central application is installed before sending the Intent - this stops your sub applications crashing and gives you the chance to show a dialog (etc.) to the user telling them the action cannot be completed.

PackageManager packageManager = getActivity().getPackageManager(); if (intent.resolveActivity(packageManager) != null) {     //You can use startBroadcast, or start activity with no UI     startActivity(intent); } else {     Log.d(TAG, "Intent not sent");     //Notify user } 

In your central application you then want to receive the intent and handle it:

@Override protected void onNewIntent(Intent intent) {     super.onNewIntent(intent);     String action = intent.getAction();     switch(action) {         case ActionConstants.UPDATE_NAME:             if (intent.hasExtra(ActionConstants.EXTRA_NAME)) {                 //TODO: Now you contact the server and carry out your update             } else {                 //No name supplied, it's an error, maybe broadcast the error back to sub app             }             break;     } } 

For the central application to actually receive the explicit intent, the activity and filter need to be registered in the manifest:

<activity android:name="MyActivity">     <intent-filter>         <!-- Note that the action matches the constant we used -->         <action android:name="com.my.example.app.UPDATE_NAME"/>         <category android:name="android.intent.category.DEFAULT"/>     </intent-filter> </activity> 

We thought of using Broad cast receivers to send the payload to central application. Broadcast receiver restrictions on Android Oreo will make this solution not viable

Don't worry about this. Use a JobScheduler or even a foreground service from your central app and you'll still be able to communicate in real time, but the implicit intents are a better choice

We are thinking to use killBackgroundProcesses

This isn't a clean approach, instead use another action for an intent, when the sub application receives it, it can finish

We thought of broadcast receiver to publish the events from central to sub applications

Again, a workaround is to have each sub app run a service which context-registers the BC - this could be in your library module so each sub app just runs it - but it is not at all a clean solution. This only matters if the sub apps need to receive the broadcast when in the background. An alternative is to use sticky broadcasts the sub apps can consume when opened.

One final thought - a slightly more complex solution for the interaction between apps would be to have each sub-app send an intent to the central app which contains the string constant for an explicit broadcast receiver (which is declared in the sub-app manifest). The central app then treats this a register event and keeps a list of all those sub-apps to explicitly contact when sending a broadcast. (It just means sending the broadcasts in a loop, to each sub-app in turn)

Answers 2

Answering the specific question and not whether your implementation is suitable or not, explicit broadcast intents and receivers in Oreo are untouched, so should work.

Differentiate implicit broadcast receiver vs explicit broadcast receiver in the manifest

Answers 3

1 Using Intents is best for calling sub applications.

2 For Communication between applications there exists AIDL although it might look a bit tough to implement but in reality it is very easy it provides a way for you to do inter-process communication in android by providing a very basic interface between applications. Google play services use this to perform In App Payments.

3 You should use account manager for this it will help share the same access token across the application suite and will gracefully handle both login and logout features.

4 This again be done using AIDL.

I also feel that you should revisit architecture of this solution as it seems all your work can be done in a single application and there seems no use to create such elaborate application design.

Answers 4

1)

Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.package.address"); if (launchIntent != null) {      startActivity(launchIntent);//null pointer check in case package name was not found } 

2) Try giving a look at content providers https://developer.android.com/guide/topics/providers/content-provider-basics

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment