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.
Related
I work on a project that has several developers.
We work on one rather large app.
Every developer has several activities that can be seen as sub-apps of the whole main-app.
I do realize, that this may not be the best design, but it exists and we have to handle it somehow.
Now the main issue is, that we need a master, that is always active and checks I/Os etc and that can give out status changes to every sub-app/activity. Something like "we just lost internet connection" etc.
Right now, that master is a singleton, that is first instantiated by the launcher activity and that every activity/sub-app can register to by passing the appropriate interfaces depending on what updates the activity would like to receive.
This is working, however it doesn’t feel right, because the singleton needs context to access system resources to determine system stati like internet or gps. Should the singleton be killed by OS, than a simple "getInstance" wouldn’t do much good, because the singleton would somehow need to acquire a context. I've read about extending the Application class and creating a static member context there, but this variable had to be volatile AND its possible that it returns null if the entire app is in some restart-after-crash/kill state. It doesn’t feel safe.
In addition, there should also be a possibility that the master somehow opens a user-dialog to display warnings etc to the user. Those warnings should look the same across the entire app and no dev should have to worry about when or why it suddenly pops up. Right now, those messages appear as custom toasts that overlay everything. Of course they require context and if the app is about to close there could be a problem.
All in all, that’s the mess we are in and I’m looking for a solution.
So how do I create a safe master object or activity (or even service ?!) that can pass info to different activities and post warnings etc (and Maybe even has the ability to close activities or at least order them to close themselves without the need to register a can_close interface).
It should be that safe, that if after a crash android only restarts the activity that was active it somehow manages to also be restarted or at least have/give the same info as before.
Every idea is welcome but total overhauls of the app are just not possible (lack of time and manpower)
Here are a few ideas:
Create a Service component for all the monitoring you need to do.
If I understand correctly, this service will be required only if
some of the activities are running. So you can make it a bound
service. Let all activities bind to this service when they start
and unbind when they close. The service will be started when the
first activity binds.
Create a base class for all your activities. You can write all the common code here. e.g. the code to bind to and exchange messages
with the master service. This class can also contain utility methods
for notifying user etc. So all activities will use the same method
for notification.
For user notifications, you could either use Status Bar Notification or create a Fragment which can capture, aggregate
and display the notifications. You can have a common menu item
implemented in the base Activity class to show/hide this Fragment.
If you use Status Bar Notification, make sure you use one aggregated
notification for your app. Otherwise, the different activities might
create a clutter in the status bar.
I guess that one solution would be to create a service that serve as the master.
You will have to make it run independently of the different activities (but don't forget to manage own to shut it down neatly if the app is no longer used, you don't want to kill your clients battery).
A service can't act on the interface though, so you will probably need to broadcast messages to the activities to order them to open a dialog.
A final thought : Toasts are ok but popup that block the interface are very bad, especially on a mobile device.
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.
I am currently working on an Android App which has different service dimensions, such as " service order", "route planning", "photo gallery" and a central login.
so far i implemented each "screen" (and by screen i mean actually the layout of a screen) as a seperate class, which loads a specific layout and handles all listeners and core functionalities such as calling webservices in a thread, receiving answers etc.
I am not quite sure if this is the best way to implemnt mulitiple layout-screens.
The Android dev guideline proposes to use single activities for each "screen layout". However I doubt that this is the most effective way of doing things. Since i need information for each "layout" which are retrieved by the central login (here: a user object). Since an activity (as far as i understand) is a seperate thread, the passing and retrieving of information seems not very practical.
I would like to get your oppinions/feedback on that and thanks for any hint or tip.
So far my structure looks like :
Activity
loads login layout (res/layout/login.xml with setlContentView)
depending on buttonclick other resources are loaded and initialized (means listeners are added etc.)
Greets
Peter
The dev guidelines recommend that for a reason. It IS the most effective way of doing things. You may complain about having to store your data so it can be passed along from activity to activity, but guess what? You're developing an app for a phone! At any point in time, the phone could ring, forcing the user to switch away from your app. Or the user could just choose to temporarily look at a different app. If your app goes back to square one after switching back and lost all data, the user will be understandably angry.
Don't know if this would be suitable for your app, but another option could be to split off the core data handling into a Service, and have your app be just a UI frontend which communicates with that service.
Im wondering what is the point of using a android service to do background work when you need to do a lot of things just to access any public methods or get a large chunk of data from a service such as a larger List object.
why not just use a simple POJO that does stuff in the background for you in a seperate thread if you like and gain access to its public methods without creating interfaces using AIDL, binding to a service etc etc?
seems soo much work needs to be done to access a method from a service class or is that really not the point of a service class in android?
i have developed a android service class that gets 100's of items in a xml structure from a web service who i then parse it into a POJO that is then stored in a List but i am having difficulty finding a way to send this List back to the activity that called this service.
i've read about using parcebales objects but that along with all the intent.putExtra have a size limitations so i may run into problems in the future.
i am thinking of ditching Android services and i have quickly found out why i dont like using them in the first place :(
a simple SomeBackgroundPojo backroundTask = new SomeBackgroundPojo(); backgroundTask.getData();
Seems soooo much easier than dealing with parcelables, serealizable objects, AIDL, binding etcc etc all just to achieve the two lines of code i just typed above :(
Nitpick: an object running a threaded background task ain't precisely what's usually meant by a plain old Java object.
If you don't care what happens to the work being done if its requesting Activity or Application is shut down, then by all means avoid services. One of the main points of Services is that they can stay alive when the user navigates away from an Activity: if you're only doing work to fill a UI ListView, by all means use e.g. an AsyncTask, as is discussed in this earlier question.
I am new to developing for android. I have a question regarding some best practices. My app is like a dashboard from which multiple different "sub-activities" can be started and done.
I am wondering what is the best way to structure the app. One way is to have different layouts and load and unload them appropriately. The other is to start new activities using intents. At least this is what i have gathered from what i have read.
What in your opinion is the best way to go.
Thanks
I've found in my applications that each Activity is generally responsible for a single UI view.
So rather than loading and unloading different layouts, which can potentially get quite messy, it is better to separate each sub-activity into its own Activity class and use explicit intents (intents that name the target activity explicitly rather than relying on an intent filter) to move between them.
The decision you have to make is whether or not your activities should be tightly or loosely coupled. Loading and unloading the activity is typically appropriate from within your own app. Using intents is appropriate when you need to open an activity that you may or may not know the specifics of. For example, you would open another activity from your main menu (assuming you have one) directly. Then later, let's say you need to open up an address with a map, you would use an intent, because you don't really know the SPECIFIC activity to open. Secondly, using intents are best for when there are multiple activities that could do the same function, such as opening a URL in a browser.
So in summary:
Open Directly (Loading a new view or using Intent specifying the Component Name)
Tightly coupled
Know specifics of the Activity to load
Open Indirectly (Intent specifying the category of Activities that can handle it)
Don't necessarily know the specifics of the Activity beyond that it can perform some action that has been advertised.
There are multiple Activities that can perform the desired action, and you want the user to be able to choose for themselves which Activity to use.
While Intents may be a little extra work, I'd recommend using them, if you don't directly need to pass large blocks of data back and forth between the two.
If you just need to pass information TO each of the sub-programs, then you can easily do that with putExtra(String key, Bundle values);
By using intents, you spend a little time now in order to have a lot of flexibility later. You can start intents from different points, so you'd not need to write new code if one of your sub-applications wanted to start a different one, or you wanted a certain filetype opened with a file manager to open one of your sub-programs.