views:

55

answers:

2

What is the difference between 2 ways of interaction between applications on android: 1. implementing service in app #1 and using it in app #2. 2. handling intentions and posting answer intention. Interactions are supposed to be asynchronous.

What are pros and contras for each?

+1  A: 

It really depends upon what it is you're trying to achieve. In the case where - as you ask - interactions should be asynchronous, there's no reason why you couldn't use Intents. This way has two advantages:

  • If it's a "general" request (something like "pick a photo" or such...) then it gives the user (and the operating system) a chance to choose the most suitable application. It's quite feasible that App #2 as you named it doesn't actually exist on the target user's device (unless App #1 specifically depends upon it).
  • App #2 can really take its time over whatever it is you've asked. If it's a user-centred task, then maybe it wants to launch an Activity and get user input, or such.

If you're looking for more technical advantages to this method:

  • You don't have to worry about things like thread safety and access control. Remember, your maintainers (which, in 6 months time is you) don't know what was going through your head when you designed an interface. A model launching & catching intents provides less opportunity for someone to make a wrong-headed decision and access a class member that they shouldn't be touching. If you've caught an intent, you can probably access all the members of your class quite safely (or if you can't, it ought to be fairly obvious).
  • You don't have to worry about App #1 depending on generated class code every time you change the interface. When you write an interface using AIDL (this is how you implement the service model you named "1") the ADT will go away and generate a bunch of classes for you which you use to expose your remote service. Problems arise when App #1 has a different version of these generated classes to App #2. (And believe you me, the error messages associated with these problems are less than informative).

On the other hand, that's not to say that you should avoid the Remote Service model altogether; it has many useful applications. This is where my explanation becomes a little "hand wavy" but hopefully you will understand the gist of what I'm saying. AIDL interfaces give you much more direct control over the services you're calling. Instead of launching an intent, bundling in a bunch of data, and dispatching it in the hope that it will reach the correct Service (or activity, or other handler), then be handled in the right way, and eventually a result will get back to you, you directly call methods within a Remote class. The methods you call in that remote class are the ones specified by the AIDL interface written within App #2 (which functions like a server) - but you will quickly start to have to think about things like threads. You're directly calling code that lives in another process - which means that a thread belonging to App #1 is being given access to objects and methods in App #2.

How you deal with the fact that App #1 is calling code in App #2 is pretty much up to you, but the way I use (and I believe the recommended way, although if someone knows different I hope they will correct me here) is to use a Handler within App #2. When App #1 calls the AIDL interface, the code it calls sends a message to a Handler living in App #2, which then gets called by a thread belonging to App #2 - meaning you know which part of your app is accessing which members etc.

There are obvious advantages to this control flow, and to me it feels more "API-ish" - but that's not to say it's going to fit everyone's purposes. My experience is also that programming via an AIDL interface is much more error-fraught and fragile. Although technically it's always just doing what you told it to do, it's quite easy to tell it to do something wrong - or worse, misunderstand what you've told it altogether. I would say: exhaust other routes before thinking about writing an AIDL service.

On the note of asynchronous calls:

  • If you simply call code in App #2 directly, it's entirely synchronous.
  • If you use a message-handling interface, things are a little different. You can then provide a second AIDL interface living inside App #1 that allows App #2 to give you callbacks (this is what happens in the example on the official AIDL documentation for Android).

So you've got there two very flexable interfaces to interact between two processes. Both are good for different purposes.

jelford
A: 

thank you for detailed comparison, it's very useful! I agree with most your conclusions. But, i think that correctly designed app facade (as service interface definition) can incapsulate any changes inside the service and partly solve the problems of changes and interface versions.

Anton