Sync between local service with a thread and an activity - android

I'm trying to think of a way on how to sync in between a local service and the main activity.
The local service has,
A thread with a socket connection that could receive data at any time.
A list/array with data.
At any time the socket could receive data and add it to the list.
The activity needs to display this data. So when the activity starts up it needs to attach or start the local service and fetch the list. It also needs to be notified if the list is updated.
I think I would need to sync my list somehow so the local service does not add a new entry to it while the activity fetches the list when connecting to the service.
Any ideas?
Thanks.

I answered a somewhat similar question here. In this answer is a link to a presentation hold by mark brady on the droidconf in berlin. In his slides he describes a framework that manages this kind of things. He also offers the source for this on github.
He proposes the following solution. Build a controller object that lives in the scope of an custom application class. The controller starts the service or a simple worker thread and notifies the UI if it gets notified by the service that something changed. He advises against the use of AIDL if it is not absolutely necessary.
The android documentation also offers an example on how to start a local process.

There are many ways to establish connection between an activity and a service and share data between them. You can communicate using following solutions:
Intents. You can send ( by sendBroadcast (Intent intent) and receive ( by BroadcastReceiver ) Intents. Example scenario: Your activity at boot moment send a broadcast "GIVE_ME_ALL_DATA" and the service sends a response. If the service has new data, it also broadcasts "HEY_I_HAVE_NEW_DATA".
ContentProvider. The service and the activity read and write parallel from it. You can attach observer to specific data-url, so every listener will be informed about changes. If You use CursorAdapter for binding data to ui components, user interface will be updated automatically.
AIDL. It's a android'a IPC. You define interface for the service which be exposed to clients. Client at the beginning: establishes connection with the service, asks for data, register call-backs. If the service has new data, it invokes call-backs registered by clients.

Related

Getting data from server regularly even when the app is closed

I want to get data from the server and store it in a cache regularly, even when the app is closed. I am not sure what is the correct way to do it. I have listed down the possible ways I can think of. Please let me know the correct or the best way to do it. Really appreciate any help.
Create an Activity and set a repeated alarm to call a service. The service should connect to the server and download the data in cache.
From a fragment, check the last time the cache was updated and then if the data is out-dated, connect to server in a background thread and update the cache.
You can Directly Use IntentService for Frequently Updating Data
IntentService is a subclass of android.app.Service class. A stated intent service allows to handle long running tasks without effecting the application UI thread. This is not bound to any activity so, it is not getting effected for any change in activity lifecycle. Once IntentService is started, it handles each Intent using a worker thread and stops itself when it runs out of work.
IntentService would be an best solution, If you have an work queue to process. For example, if your application using analytics you will likely to send event name and related parameter to your tracking server for each user generated event. Although each event means a tiny piece of data, creating networking request on each click will result an overhead to your application
For implementation : Updating Data from Server Using Intent Serive
Do take a look at Android Sync Adapter Framework.
https://developer.android.com/training/sync-adapters/index.html
Hope this helps.

Android app advice, multiple intent services?

My app has a UI and a connection is made to a bluetooth device which is periodically sending barcode scan data to my app. I then want to cache this data in a sqlite db and have another process push this data up to a web server.
I have managed to get the UI and bluetooth scan process separated by using an Intent Service for the scanner component... The thread in the intent service connects to the bluetooth device and loops endlessly pulling in new scan data as it comes... communicating with the UI via broadcast messages as it needs to.
So now I need to handle storing the data in a sqlite db and pushing it up to the Internet.
I'm thinking I can insert a db row directly in the intent service loop I already have working for the bluetooth data... would I do that by firing of an async task or something like that?
Then, would I have a completely different intent service running and looping endlessly checking for new records to be processed and pushed up to my web server via an http post?
I guess the main reason I'm thinking of using intent services is that they seem to keep running even if I lock my phone and put it in my pocket... has worked so far for the bluetooth barcode scanner... can scan away happily with my phone locked and in my pocket.
I also need to handle the reality that internet won't always be available... hence the sqlite db... kind of like a safe buffer to store data until it can eventually be pushed up to the Web server.
Am I going down the right path? I'm really new to Android development and even after much research I'm still unsure about my approach.
You can store data or communicate from IntentService onHandleIntent() directly. You don't need to run it in separate thread, unless you want reading bluetooth to continue ASAP.
Handling everything in an infinite loop smells. Also keeping service alive depends on few factors. If IntentService dies, it won't be restored because by default IntentService.onStartCommand implicitly returns START_NOT_STICKY, or START_REDELIVER_INTENT if you call setIntentRedelivery(true) on this service. Check Service javadoc for more info.
If you can scan bluetooth periodically then I would consider kind of scheduler. For that you would probably need to implement Service, not IntentService and handle background thread yourself. Alternatively, you could use a Timer. These are more hints, not ready solution. Since you asked about direction, I assume you will investigate solutions yourself.
Depending on handled data you could separate DB operations and network to separate services. Think about them as modules which are decoupled. You will benefit maintaing this code in the future and in case one service goes down due to any reason, the rest will keep working. It depends on data size because it's not a good practise to push heavy data between service/activities(data is serialised and deserialised every time it is sent).
If DB is just a buffer/queue then maybe use it directly after reading bluetooth data. In other words queue data for sending. Create second service for HTTP communications. Don't push entire data to second service, just inform it about(knock the door :)) and let HTTP service access DB by itself. I would wrap DB in ContentProvider and access it from services.
There are probably different techniques out there too, but that's what I thought about it in the first place.

Downloading data and updating UI

There are couple of things that are bugging me in the process of downloading data and notifying the UI in Android. I'm using (Intent)Services to download the data, which works good enough.
I'm not sure how to deal with notifying the UI that data has been retrieved though. After some research and discussion in Downloading data using IntentService - Lifecycle Changes, and Which is the best way to communicate between service and activity?, I'm arriving at a point where I'm not sure which method to use anymore.
The alternatives I'm looking at are:
Service + LocalBroadcasts + Databases
An Activity would start the Service
The Service would download the data into a database
The Service would send out the Broadcast with a 'done' notification
The Activity would pick up this Broadcast and retrieve the data from the database using an AsyncTask
The Activity would retrieve the data from the database using an AsyncTask every time it is shown to the user (onResume, for cases it has missed the broadcast due to the user navigating away).
Service + ResultReceivers + Databases
An Activity would start the Service
The Service would download the data into a database
The Service would notify the ResultReceiver that it's done
The Activity would retrieve the data from the database using an AsyncTask
Instead of retrieving the data every time, the ResultReceiver is reused across lifecycle changes, and notifications are not lost.
Service + ResultReceivers + Bundle
An Activity would start the Service
The Service would download the data (optionally into a database)
The Service would notify the ResultReceiver that it's done, and supplies the data in a Bundle.
The Activity would retrieve the data from the Bundle (No AsyncTask needed).
Instead of retrieving the data every time, the ResultReceiver is reused across lifecycle changes, and notifications are not lost.
Options 1 and 2 require the user waiting for the database read/write operations. Option 3 is therefore quicker, but I've seen many sources recommend not using Broadcasts or ResultReceivers to transfer data (I'm not sure exactly why though).
For now, I am sticking with option 3, but I'm not sure if this is actually a proper approach, and if I'm missing something.
Can someone shed some light on this?
While some people (possibly righteously) vote this question to be opinion based, I am looking for pitfalls I am possibly overlooking. Furthermore, I'm looking for the answer as to why using ResultReceivers or Broadcasts for sending result data is recommended against.
Carefully using some sort of DataManager singleton instance, backed up by a database seems to be a robust solution. Using ResultReceivers, the UI gets notified and pulls the data from the DataManager.
I have also found out that using ResultReceivers and Broadcasts to send data has a negative impact on performance, because the objects need to be serialized. This is a costly operation, and GC might kick in because of it.

Android TCP/LocalService

I am new to Android development and am not sure of the best way to go about handling the following problem.
Background:
I have a TCP client running on android talking to a server. this is up and running just fine however when moving to the next step i am unsure of what to do.
Problem:
I have a UI that draws based on a users touch. I need for the tcp client running on the phone to send the coordinates and some other data to the server. Also there are multiple activities in this process that would be sending data.
What would be the best way to handle this?
Here are some of my thoughts.
1) A class that would have a Runnable client that works on another thread (I think its is an invalid solution because it would not be easy to use the same connection on multiple activities)
2) A local service that can the main activity can start and the rest of the activities can bind to it and send data to it.
If the correct answer is number 2 I am a little confused on how a service like that would work. What I am thinking is that in the OnCreate() method of the service it will launch a tcp connection with the server. Once the socket connection is established I am a bit unsure of how to actually keep in communication with the service and give it the data it needs to send over the client.
You would start the service with startService(). Include in the Intent extras that contain your data to send to the server. The service would retrieve these extras in onStartCommand() and would have a background thread actually send the data.
Be sure to stop the service when you are done with it.

android application design

I have to develop an application where i have to continuously collect the GPS, accelerometer data [esp. when user is in motion i.e traveling, else it can be relaxed). Also I have to communicate with web server and handle the response from the sever. So for this(handling response ) part application should continuously poll.
Based on response from server I have show UI to the user.
I am not very clear about the design.
Do I have to create activity from where I start service. Should service be ran as a separate thread(this always runs in background).
I am planning to create two services. One service to continuously collect GPS data.
Other service for communicating with the web server[start timer/alarm manager] for polling.
ALso can these two services communicate with each other.
Also after processing the response frm server the service should be able to start user interface to show some form. I am not clear how to handle this.
Also is acquiring wakelock required if I have to collect GPS data continuously.
Please clarify.
Thanks
You can use an AlarmManager for polling. You just need to set the interval. You will notice that most components Application, Service, Activity all are Contexts. So they all can get Application Context. The way to think about communication is that the android message/event is essentially the Intent. So you define your custom Intents. You just need to give them a custom name for the action. Then you use Intent filters. You can do point to point messaging by doing startService, startActivity or you can broadcast the intent. I would recommend that you communicate via broadcasted intents. Message routing is handled using Intent filters. Starting form etc would just be a startActivity(Intent) and the Intent itself could contain using intent.getExtras(). Just so long as you can put it in the Bundle you can pass it and display. So to answer your question, just use Intents for everything. Use broadcasting and filtering for communication and Intents again to start your activity for display.
The May 10th Google I/O had an afternoon session called Android Pro Tips. The first section covered several different approaches to making your app more continuously location aware.

Categories

Resources