I am trying to create an android application which is essentially a platform for other developers to use(let's say a mobile health platform). In this platform, I am trying to implement a component based approach. I have several activities, a main logic thread(or service), and a couple of other threads and services which provide data.The main logic is where the developer will be working.
The question is, is this a good architecture considering android environment? If so, I am thinking of using Messenger class to provide communication between these components, is this the ideal solution for performance?
And also should i control the passage between activities in main logic, for example if user presses a button which launches an other activity should i send a message to main logic and start the next activity from there or change the activity from UI thread and let the main logic know about the activity change? Which leads to my next question how can i connect an activity to an existing thread(May be passing the threads Handler?)?
I am a beginner so i can't see clearly what problems might occur so I wanted to ask to be sure.
For those who might be searching the same answer :
Turns out using Messenger was the perfect solution because it could be used for interthread, interprocess and thread-process communition with a sufficient performance rate.
But keeping ui dealing with it's own management was the better solution and i just had to report ui's state to my main thread which had control over all other components.
Related
We have an Android app which consists of two main components:
The main UI (several activities) and a background service running endlessly without any direct interaction with the UI (both writing/reading from the same database). The UI is often used by the users but not that much. The background service should run at all times.
Currently we are using Flurry but we did it all wrong. Since events are coming from both the activities and the background service, it corrupted our session settings, active users and so forth. We want to make things better.
We've decided to replace Flurry with Google Analytics (SDK v3 improved a lot since the last time we examined it). We created two different properties with different tracking IDs (one for the UI and one for the service). Our plan is to use the EasyTracker with the UI (much simpler in measuring session times and screens flow) and use a manual tracker for the service (https://developers.google.com/analytics/devguides/collection/android/v3/advanced#multiple-trackers)
We have two main concerns:
Is it a good idea to separate the UI and the service into two different properties?
Should we measure session times for the service? We do want to know how many users are actually running the service but session time is irrelevant in this case. Is there any other event we can use just to know how many active service users are there?
Any thoughts, remarks, suggestions or insights would be highly appreciated.
Thanks, Alik
I'm starting to work with Android, and as far as I have read, the main structure of an app is a group of more or less independent Activities where one is the main, and from there you launch one or another.
My problem is that some of those activities spend some time when they are created to generate some data, that is lost when the activity ends because of the paradigm of Android.
Also, I want to have some overall control of some parts of my program. For example, I activate a sensorListener in one activity, and I want to keep it working after I end that activity (by pressing "back" or launching another activity).
Is it possible to have some common structure to all the activities where I can place reusable data?
Also, I whould like my app to do something periodically , no matter what activity is working at the moment.
Do you know if there is a "well designed" way to program this overall data structure and periodic tasks?
You can use your "Application" class to have an entrypoint. This class won't get dealocated, you can save references in there, however, this is not a good style of programming but I have seen it a lot. If it's possible, a better way is to use threads, e.g. "AsyncTask" class. Here you can perform your operations and populate the activity on the fly.
As L7 pointed out you may use "service" as a long running background process for your sensor, this is also the recommended way of android.
First I'm sorry for my english that is not so good :).
I am facing a problem to develop my app.
That is a general architecture scheme of my solution.
http://i.stack.imgur.com/ooTmE.png
To be quick, the app has to decode code bare but with two possible ways:
using exernal device (The constructor provides a sdk containing an android Service to communicate with the device),
use the camera of the mobile using the library Zxing which is possible to manage it with intent.
The goal of my own service is to manage some business code and make transparent the choice of the tool for the user.
I believed that was a good solution but I wanted to implement it and I had different problems.
My main trouble is that I cannot execute StartActivityForResult inside the service.
Do somebody have any suggestions for my problem whether a change in the architecture or a solution for the main problem?
#Laurent' : You have totaly right my service acts as an API adapter.
I will try to make the expected behaviour more clear.
I have an app that needs to recognize (real) objects which have QR codes on their top. This recognition action will be done several times by the user during the life of the app.
The user chooses to launch the recognition by clicking on a button (or otherwise but he knows that the recogntion will start). So no notification is needed.
The thing is he doesn't choose the way to do the recogniton. It is why, as you said, I implement an adapter.
The adapter chooses between :
Camera mobile or external device. The first is an activity coming from the Zxing library. The second one is a service that manages the external device. This service provides an interface to get back result.
One more thing, I need that my whole implementation (adapter and co) can be re-used by other apps that will also need to do recognition.
So my thought was to implement a service as an adapter to answer my two conditions (make transparent the choice for the user - and make the recognition available for other apps).
I hope you understand my problematic.
Given your architecture, your MyOwnService must act as an API adapter : it should provide a unified scanning API and address each external service specificities transparently.
Your expected behaviour is not clear enough to provide a solution that suits your needs but here are a few remarks that can be of some help.
Passive scanning:
Even if there are some workarounds : no activity should be launched from a service (not directly). Never. Bad. Services are background stuff, the most they will be permitted is to hint users with Notifications (this is point 2 of Justin excellent answer).
As a consequence there's nothing as a 'popup Activities' (and that's good!). If you need to continuously scan for barcodes, even when your activity is not run, then the only way to warn users is by using status bar notification.
Active scanning:
Inside your own activity you can bind to your wrapper service and make it start scanning for codebars. When it finds one it has to message your activity. Your Activity message handler has complete access to the UI to inform the user of your findings.
You selected Active Scanning in your edit, your problem is therefore to find a way for your service to actively notify your main application (the one that started the active scanning) that a new item has been scanned successfully.
You do NOT do this by starting a new activity (remember: this is bad) but you can bind to a service and/or use Messages between the wrapper service and the application.
I advice you take the time to read (and more time to comprehend) this android developer article on BoundServices and especially the part about Messengers.
A full example of Two Way Messaging between a Service and an Activity can be found in the following android examples : Service & Activity
Warning: designing robust, full blown AIDL-based services is a tough job.
Two ways you could solve this problem.
1) Have MyOwnService do a callback into MainActivity telling it to launch your ScanActivity.
- This is a better approach if MyOwnService's task is only going to be running while MainActivity is running and if the user would expect the ScanActivity to come up automatically.
2) Have MyOwnService create a notification that will let the user access the ScanActivity.
- This is a better approach if MyOwnService's task might be running longer than the life span of MainActivity. That way, you can let the user know, unobstrusively, that they might want to access the ScanActivity.
So finally I changed my architecture.
I make the choice to delete myOwnService and to create an intermediate activity that will be my API Adaptater.
This activity will have a dialog.theme to look like a dialog box indicating that a recognition is under execution.
If the recognition uses the external device this activity will stay at the foreground otherwise the camera activity will start (Being managed by the intermediate activity).
Thank to that I can manage my result from the intermediate activity and do not have an android strange architecture, keeping my business code for the recognition outside my main app.
Service was not the good choice.
Thanks a lot for you help and your time.
how does a good architecture for an android app look like? Should all the "work/business logic" been done in a background service and the Activity communicates just with the service to query/fetch data from somewhere (local/distant)?
Would you implement the "service" that the Activity calls as a real Android-service? Or a POJO-Singleton that does the work (perhaps using background threads). Or instantiate background threads in your activity for time-consuming actions (query a webservice).
How do you abstract your data access the right way? Would you use a ContentProvider to access/abstract your data? How/From where should it be queried? Activity? Service? ..?
I've tried to search for a good app architecture design, but I only found how the Android architecture looks like, not how an Android app should look like.
So what's your opinion about that? What components of an Android application should communicate which each other to ensure best extensibility/encapsulation,...?
There's no one answer to this question. Good OO design isn't Android specific. I'd say that the rule is - if the framework gives you a high level object (such as Service in the case of Android) that fits your use case, use it. If you find yourself making POJO implementations of the same things you get for free with the framework, go with the framework.
As far as separation of concerns, this is standard OO stuff. Don't put anything in your Activity classes that isn't the job of the Activity. Over-stuffing the Activity with methods and properties that the Activity needs but aren't really the job of the Activity is bad - makes the intention of your Activity hard to understand.
I usually separate stuff into sub-packages in my apps.
com.myname.myproject.app - base classes, global application functionality
com.myname.myproject.net - network stuff, network related utils
com.myname.myproject.data - db helpers, providers, etc
com.myname.myproject.model - object model
etc.
As far as communication within your app...
I always have a custom Application class that I register in the manifest. This way, when I have controllers and helpers that need to be a "single instance", I don't have to do all that crazy thread safe singleton stuff...I just keep one global copy of.
RoboGuice is a dependency injection framework that makes this even easier to accomplish...definitely worth looking into. If this interests you, the Google Group for RoboGuice is great and is constantly filled with the creators of the framework who can basically answer anything you need.
As far as in-app communication, I use my single instance Controller and State classes to hold state and do common tasks, and I usually use BroadcastIntents to communicate back to Activities from Services
What is the difference between these two ways of interaction between applications on Android:
Implementing service in app #1 and using it in app #2
Handling intents and posting answers to the intents.
Interactions are supposed to be asynchronous.
What are pros and contras for each?
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 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.