I'm building a fairly simple data tracking app. Using a runnable, every 5 seconds my app checks how much data the user has consumed and updates the UI.
The app works well, and the runnable keeps going even when the app is not in the foreground, but when the app is closed, it stops.
I've never used a service before, and after reading some documentation, I'm still unsure if that's what I need. I need to be able to update the UI, and depending on the data amount, start an asynctask to update a server.
Right now this part is happening from the runnable, but from what I've read about services, it seems like interacting with the UI is difficult.
I was originally hoping that I could somehow just prevent the app from ever being killed. It's going to be used on a private system, so there's no concern of the user 'getting annoyed' that the app can't be closed, but I can't figure out how to pull it off.
Thanks in advance for any information!
Note: I didn't post any code because I didn't think it was relevant here, but I'd be happy to upon request.
Is this the correct situation to use a service?
Yes.
from what I've read about services, it seems like interacting with the UI is difficult.
It's not that hard. The easiest solution would be to use an EventBus.
Another solution without a library: The Activity binds to the Service in onCreate. The Service returns a Binder. The Activity passes a Listener to that Binder. The Service calls the listener as soon as the UI needs to be updated.
Related
I am planning to implement Socket.io in android by this library for a chat based application. As far as I understood the library seems to be pretty good. I want to know how to maintain a single socket connection throughout the app all the time? Here I have listed out ways to achieve, in which I need the best and stable way.
Three ways
MainApplication Class extends Application
By this we have a good scope that the socket connection is maintained in the main thread( or application's life cycle) and whenever the socket instance is needed from the activity we can get it easily. But it's main thread which also the problem. It might block the main thread.
BoundService
By this way we can bind the service with the activities and we can simply use it. Doing in separate thread is the way to achieve IO/Network calls. But cross processing transfer is more expensive than directly accessing in same process.
Singleton
Maintaining connection in Singleton also makes sense. But we don't know when the instance is killed by process, because it doesn't work in activity life cycle.
If I makes sense please help me out. If not comment it out.
Edit
I have given the answer which is more suitable for me.
First of all, the Application's onCreate() is irrelevant in your use case because you can't have a thread running in the background when it was first initiated in a non service code.
Also, I would recommend using Google Cloud Messaging instead of creating your own mechanism. It would be best for the device's battery life and much less code for you to handle.
If you do want to implement that chat completely on your own, Service is your only choice. You can also combine it with a singleton, but I wouldn't recommend that approach. You can use broadcasts and BroadcastReceiver for communicating between your Service and Activity, I think it is easier than a Bound Service since bounding to the service is asynchronous and it creates a lot of mess compared to simple broadcasting.
Service for Maintaining socket connection
As per Ofek Ron mentioned Service with BroadcaseReceiver is a better idea than BoundService. Because its a tedious process to maintain communication. And I also recommend pub/sub way of broadcasting, like Otto or EventBus (I myself suggest Otto by Square, which is clean and brilliant api).
Pros of OTTO
1. Cleaner Api
2. You can subscribe and publish in/to any Activity, Fragment, Service class.
3. Decoupling. (You have to couple as less as possible in your code).
And one more point is use START_STICKY in the onStartCommand() to start service after it is getting destroyed. See this reference.
MainApplication to start the service
It's best practice to start the service in the MainApplication that extends Application. Because the application will be killed when there is a memory constraint or user forcefully closes the app from the stack. So onStartCommand() will not be called frequently like if we have implemented in Activity.
Implementing online status
You can implement online status simply by implementing Application.LifeCycleCallbacks in the MainApplication class, which has most of the life cycle callbacks of activity and will be notified in the callback. By that you can implement Online status simply without any boiler plate codes. (If anyone need help here let me know).
Uploading or downloading images or files.
Best practice is to implement by IntentService because it's running in the a separate thread. I promise which will give the best performance because it is handled by android itself, not like threads created by us.
You can combine first way and third way like:
Create Sockets in your Application and declare them as static. So you can maintain and access them every where in you application. Don't forget to create separate Threads to perform the network operations, you can use ThreadPool to manage those Thread. If you want to update your UI from those Thread you can use Handler and Message to communication with UI Thread
Before you create your own implementation of a socket.io client, you should give this library a chance: https://github.com/socketio/socket.io-client-java
I use it in one of my projects to communicate with a node.js server which is working pretty fine. Actually, all of your suggestions are correct and mostly depend on what you want to achieve. However, one context is always available: the application context. Therefore you should keep a singleton instance in the Application class and get it by getApplicationContext().
Online status of the user: here you should create a background service which is listening constantly for the users state. As there are not many information, this should be okay and should not drain the battery too much. Additionally you can send a flag if there are new information available and only if there is something new, you start another thread, which is receiving the new data. This keeps the data low.
Chat: the chat data is transfered only when the app is active. So, this should be done in an activity.
Both the service and the activity can access the singleton instance of the socket.io client from the application context. As long as you do not process any complex data on the main thread everything is fine. So, wrap your calls into separate thread and only start them when they are actually needed.
I'm trying to implement an android app where I can send commands to a server that controls a robot. The problem is quite "simple": I would like to keep a connection and communicate with the thread-service-task to send messages to the server, and get the responses to update UI and keep the user with the related information from the robot sensor.
So, what should be my decision? I know its probably duplicated. But I didnt find my same problem, cause I want to extend the question:
Is there any way to run a background process on an activity, change activity and keep it going? (Activity or fragment, I would go for fragments in the future).
Thanks in advance for any help!
The best solution for this is probably a Service.
A very good article on Services, including how to communicate with a background service via either Intents or broadcast events can be found at http://www.vogella.com/tutorials/AndroidServices/article.html
One typical model for your situation is to use:
Service for long running communication (taking "orders" from a queue
BroadcastReceiver to be notified about asynchronous events handled by Service
Activity to handle UI
One reference to consider looking at is here
Here is a Reference Code that uses an Android App , Arduino to Control a Bot. You can see its Structure thats what i have used in my robot as well. AsynkTasks wont be a good option in this aspect. Using a Service is a goodIdea for Long Running Communication
https://code.google.com/p/mover-bot/
Here is a Live Demo of This Android Controlled Robot.
Mover Bot
Do your work in Background and notify the result to UI thread.
Go through this for more detailed overview.
AsyncTask
It is a helper class around Thread and Handler for making threading and easy for you. Just do your task in background and publish result in UI thread.
http://developer.android.com/reference/android/os/AsyncTask.html
Thread
Use basic concept of threading in java, create your own thread pool do your task and publish your result in UI thread using handler. Mainlly, used when you need more longer running task while your ui is visible (for simple background task asynctask). It will take time in implementation but provide you more control over task management.
https://developer.android.com/training/multiple-threads/create-threadpool.html
Service
Services are used when you have more longer running task and also you want your ui to be independent from your task.
Here in your case i would prefer you should use a service for communication and use binder or broadcast manager for reflecting change in UI.
http://developer.android.com/guide/components/services.html
I've been working on an app, and it's came long great. I have a problem though, Android, being greedy with its resources, loves to kill the app when I put it in the background. This is very bad, because the app is actually intended to be an AI assistant, and having to reinitialize every-time I need to use it means that it's not going to be very helpful in a real work environment.
I investigated ways to prevent reinitialization of the AI's brain, however, none of the methods have been very fruitful. Saving the instance of its brain will not work, because the POS models that she needs to operate can't be serialized. And employing a service won't work either, because if I want to communicate with the activity via the service, I have to reinitialize it along with the activity (correct me if there is a way around this, I just notice most tutorials put service.start() in the onCreate methods)
Is there a way around this? I only need to preserve the POS models. They take a while to load in for some reason despite only being a few megabytes.
Please note that this is to prevent data from being killed. There are no background processes that need to be ran.
You need to set a Notification to tell Android not to release your resources.
See this question: How can we prevent a Service from being killed by OS? . While the question itself is not directly applicable the answers have a lot of overlap with this issue.
You should probably be using a Service if you want to run things in the background though as Activities are only supposed to run when you have a layout in the foreground. You could store your required object in the service, grab it as necessary when (re)starting an Activity that requires it and update it when your Activity loses focus.
Edit: I accidentally pasted the wrong link. Now corrected.
Also, have a look at this Android resource if you have not already: http://developer.android.com/training/basics/activity-lifecycle/recreating.html
i've a question for a feature, i want to implement.
I know some applications, like whatsapp, gmail or others, which run in background and notify the user, if something is received...
i'd like to do the same with my application. i've a http-network-connection and want to notify the user, even if he hasn't the application started. is something like this possible?
Is it possible, that a PopUp-Window, like receiving a sms, appears?
(if not, the notify-way in a titlebar is enough)
i've no idea, what i should google or where i can find help
Thank you a lot!
Edit: I found another very cool framework which deals with notifications. Have a loot at: https://www.parse.com/tutorials/android-push-notifications
You should take a look into Services. You can have the http connection listening in it. For the notification I'd use the NotificationManager class. A notification is much more less intrusive than a pop-up.
Hope that helps
Google Cloud Messaging will definitely help you.
If your server can instantiate this 'action' or 'event', by all means don't try to pull data periodically, coz that brings extra complexity to your app and also battery drain to your users.
But if you really, truly, badly need this behavior, you can instantiate a Service from your app's process. This can be done from many places, like your main activity or some other user action, or even from a broadcast listener. For example, our app has some parallel work to do, so we pass this to a service and that service is initiated by a broadcast listener listening for phone events like a phone call or sms.
On the other hand, just like the main activity of your app, your background service can be killed arbitrarily by the operating system any time. So you shouldn't depend on it running forever. You should have ways to check if that is still working in the background. Check alarm events or any other relevant broadcast listeners.
A very simple question:
I know that Android applications run in the background when they are closed. Is it possible for my application to keep working while it is in the background? For example, maintaining a timer in the application to automatically perform a function every hour?
Thanks!
Use services for doing tasks in background. more info is here http://developer.android.com/guide/topics/fundamentals/services.html.
An alarm service should meet your needs; here's an example.
To run things in the background (or outside of the main application thread) there are a few options. To do something very quick in the background the easiest way is to use an AsyncTask. It sounds like you are wanting to implement a bit more than an AsyncTask would handle though. For more longterm tasks that you want to run behind the scenes you probably want a Service.
You can have services that run, do what they are supposed to do and then exit, and you can have ones that keep running. Services have a lot of depth. You could use the AlarmService that is linked above by another user, however another approach would be to just make a simple service and use a TimerTask http://developer.android.com/reference/java/util/TimerTask.htm
Remember though, when you are doing things in the Service, they will be being done on the Main Thread, which could slow down other programs, so any logic over long periods of time needs to be accomplished in an AsyncTask.