0

I am looking for some design patterns to use controlling a set of Activitys in an Android application. I am currently developing an app which I feel will go under many many revisions of the UI until its "final" release (if there ever is one). I was thinking something along the lines of an Observer pattern using a controller in the Service but I can't find any good examples. The only thing I find common references to is using AIDL for inter-process interface binding, which will not be applicable.

Basically what I want is for the Activity to implement a defined Interface such as showLoginScreen(), loginError() etc. such that ANY UI should be able to implement (the controller is not tied directly to the view, only its interface). If this is the cleanest way to accomplish this, what is the best accepted way of getting handles to active Activitys? I have always been confused what happens when you invoke a method on an Activity that is not active.

I was thinking something along the lines of a Map in the Application class serving as a singleton? The put() / remove() of the Map would be tied to onStart() and onPause(). This still doesn't guarantee the Activity is still alive though...a reference could be gained with a get() on the key, and then it could be paused() before the Service has a chance to call its interface.

Any suggestions or insight would be appreciated.

edit: I have looked at other posts such as MVC pattern on Android however they mostly don't address implementation (and that accepted answer I just flat out disagree with anyways)

Community
  • 1
  • 1
Ryan
  • 3,579
  • 9
  • 47
  • 59
  • Why do you want to have multiple activities? Does each Activity represent your View in the MVC? – Noel Jun 11 '11 at 23:54
  • Each Activity is a separate screen that the user needs to interact with. They won't be multiple activities trying to accomplish the same task. Aside from full screen 3D games, I don't know any application with only one Activity. – Ryan Jun 11 '11 at 23:58
  • Have you considered using a single Activity as your controller and then switching the screen/View dynamically at runtime? – Noel Jun 12 '11 at 00:04
  • 2
    ^ This is a poor design decision on Android as you lose the flexibility of xml configuration. The OS can no longer automatically chose the best layout for you, instead you have to manage all of this yourself – Ryan Jun 12 '11 at 00:10
  • I don't follow. How does Android determine the best layout for you? Do you mean between portrait and landscape? – Noel Jun 12 '11 at 00:15
  • http://developer.android.com/guide/topics/ui/declaring-layout.html – Ryan Jun 12 '11 at 00:22
  • Right, so it's done via the setContentView() call. If you use that method to set the view, in a single Activity, how do you lose android's ability to chose the best layout? – Noel Jun 12 '11 at 00:26
  • "For example, you can create XML layouts for different screen orientations, different device screen sizes, and different languages." The OS picks the most appropriate XML you have dynamically based off of screen size, language, resolution, and orientation. That's an enormous amount of overhead, on top of trying to jam your controller into a single Activity who may not even be active because it has been paused by the OS. That is why it's the service's job. – Ryan Jun 12 '11 at 01:01
  • You still haven't explained what the difference is, if any, that android will provide. With a single activity vs 10 activities, you're always calling setContentView() to set the view. The orientation, etc, is all handled via different xml files. I don't see why you would be sending messages from your service when your Activity is paused anyways. – Noel Jun 12 '11 at 01:04
  • I'm not really sure what is not clear. I believe what you are suggesting is to programmatically construct your views based off of a set of conditionals in your code? Doing such things is consistently marked as bad practice in every Android book I have ever read. setContentView is only called upon a resource, so your method will do no such thing. Furthermore, your suggestion of one giant class versus 10 split up activities is akin to saying just make one giant java class instead of breaking it up into modular sections. It's generally bad practice for maintainable code. – Ryan Jun 12 '11 at 01:09
  • I think I understand what you're saying. You don't want to have a massive switch statement to determine which resource to use. You are correct in saying this is bad practice. I thought you meant that you would have to switch between the layout-land/ vs layout/ resources. Regarding, the one giant class, you can always use composition to create a modular design and it does not necessarily have to be done via different Activities. Regarding your other questions, I've posted my answer below. – Noel Jun 12 '11 at 16:27

1 Answers1

1

To use an observer/observable pattern between your activities and your service, you will need to use Bound services.

This way, you can get a handle to the IBinder which can act as your Observable and you do not have to worry about AIDL. You can ensure that the Service has been bound to in the onServiceConnected() method in your ServiceConnection. Keep in mind that your service will only be alive as long as there is an Activity bound to it, otherwise it will be stopped.

I would recommend reading the android Bound Services documentation as it explains the usage very well.

Noel
  • 7,350
  • 1
  • 36
  • 26
  • Thank you very much. Could you clarify what would happen if the Activity registered itself as an observer to the Service, and then an event was fired, iterating all of the registered observers and comes across one that is not active? – Ryan Jun 12 '11 at 17:22
  • I would actually unregister the activity and unbind from the service in the onPause() or onStop() of the activity. Then, bind to the service again in the onResume() or onStart() and register the listener in the onServiceConnected(). In my onServiceConnected(), I would ask the IBinder (or whatever your observing) for the latest version of whatever I'm observing in the model. Does that work for what you are attempting to do? – Noel Jun 12 '11 at 17:57
  • Yes, it does, I was interested what "race" conditions if any there were... we shall see =P Thanks again. – Ryan Jun 12 '11 at 18:37