Best approaches to refresh data periodically in Android - android

I have two cases in which I need to update data from webserver using API in background. To obtain data on request I use okHttp and Kotlin courtines. And now I am wondering which approaches are the best, when:
I have listview with data from webserver, and I want to update it, let's say every 10 secs, when application is in that certain view. (I was thinking about using for ex. handler with runnable)
I want to display notification when some data will change in some certain way. In that case I think that I should use background service?
With regards,

You might be looking for services: https://developer.android.com/reference/android/app/Service
You can think of these like background processes (they're a bit different, though) These run in the background and interact with other Android components like notification manager (https://developer.android.com/reference/android/app/NotificationManager).
So, essentially, you'll want to create a service to check the API every minute or so, then add a notification to the manager.

IMHO the best approach is to build for offline: store your result in the persistent store (i.e. Room). Subscribe on the query result for your feature. Then you can use the new JetPack's WorkManager for the regular updates ( https://developer.android.com/topic/libraries/architecture/workmanager/ ). Here is the slightly modified code snippet from the documentation:
val dataCheckBuilder =
PeriodicWorkRequestBuilder<DataCheckWorker>(10, TimeUnit.SECONDS)
// ...if you want, you can apply constraints to the builder here...
// Create the actual work object:
val dataCheckWork = dataCheckBuilder.build()
// Then enqueue the recurring task:
WorkManager.getInstance().enqueue(dataCheckWork)

Related

Display real-time data in ListView

How to automatically update UI with the new tasks?
For example, while I'm on the tasks page, I load them once. In the meantime, let's say new task are created and stored from my web application to mysql db. I would still see only previously loaded tasks without any idea that the new record is created in the database.
I'm using ListView.builder to display the data, while calling the API on initState(). Also, it might be worth noting, I'm using Laravel with MySql for my backend.
What is the best way to update UI with new data whenever there is a new record in the mysql database?
i have one solution to get real time record/Tasks with out page refresh on UI.
steps
1)Add new column name (is_seen) on Task table default is 0.
2)when tasks list you will show on front end then add is_seen =1 for all that Tasks that you have to show on front end.
3)Run ajax call in interval in Task Tasks Ui page that run after some interval like 3 sec etc and get all unseen tasks (condition is is_seen=0) on Ui Tasks page.
4)when new task create on table that will have is_seen=0.ajax call get that task and show on Tasks list on front end
5)then same time after rendering on new task on task list send ajax call to set is_seen=1 of that task.
I hope you understand this.
This might need a little bit of a more complex setup, as you are trying to build an app that is sort real time.
You could go explore Polling -> where you make call to the api endpoint after an interval of say 30 seconds
Or better yet you could explore websockets.
I would argue websockets is the better alternative.
Polling doesnt require any change on your backend, just a timer countdown of sorts -> Have a look at this : https://api.flutter.dev/flutter/dart-async/Timer/Timer.periodic.html.
For websockets, Pusher ,an abstraction of the low level websocket implementation, is quite common on Laravel and quite straight forward to setup. You could start with with the with this closed source option https://pusher.com. Its easier very well documented and has pretty well maintained Flutter package.
On your flutter app, I would advice a better form of state management like Bloc or RiverPod coupled with the Pusher flutter package (https://github.com/pusher/pusher-channels-flutter), to subscribe and listen to channels and events. The state management bit is just to enable you to work with streams and to have cleaner and maintable code.
Depending on how you architecture of streams you might also need to explore the Streambuilder widget

What solution is better for sync offline-mode app with server once a minute

I've made Android app that uses offline-mode. Also it has button "Sync", on click - syncronization with server is performed (server is not Firebase-service DB).
I want to do the same sync without this button once a minute when my app is on foreground and when network connection is on.
WorkManager seems the best solution for the usecase, but according to this article minimum interval for WorkManager is 15 minutes.
Other ways described in this article are: ForegroundService, AlarmManager and background Thread.
Also I found solution Sync Adapter
What way would be the most efficient for the case?
P.S. I understand that this scenario is not very clean and probably the best would be add online-mode and switch between two modes without frequent syncs. But I have some reasons at this time not to do that
Finally, I chose next way:
To invoke one-minute sync I used ThreadPool. This discussion helped me to choose.
Inside my Application class I put that code:
val scheduler = Executor.newSingleThreadScheduledExecutor()
scheduler.scheduleAtFixedRate({
.... <My Sync Block> ....
}, 0, 1, TimeUnit.MINUTES)
To prevent getting the same data from the server (there could be huge pieces of data in my case), I had to use MD-5 alghoritm on the server-side. It works as follows:
server emits data with hashes (for each piece od data)
mobile app gets data and saved both data and hashes in SQLite. In next sync app sends hashes back in request
server looks if requested data has different hashes and includes only updated data in respond

Is there a way to execute a chain of work items periodically in android WorkManager

I am developing an application and have based my content fetch on WorkManager. I have a chain of work items that i want to execute periodically. My concern is that as per documentation here
I can not use a periodic work inside a chain of work items , but can I execute a chain of work items periodically ?
I have explored multiple posts but have not found the exact answer.
Your PeriodicWorkRequest can in turn enqueue a chain of OneTimeWorkRequests. That's probably the best way to accomplish what you are trying to do.

Send data continuously from one android application to another

I want to send an unsigned char array from one android application to another continuously in a loop. I know how to send data once. But I need the first app to run in background and send data consistently to another app that performs operation on that data.
Any suggestion will be helpful.
Thank you
There can be many ways but one is to use WorkManager for this purpose. You can schedule or repeatedly perform operation of sending data from one app to another.
Beauty of WorkManager is that WorkManager might use JobScheduler, Firebase JobDispatcher, or AlarmManager. You don't need to write device logic to figure out what capabilities the device has and choose an appropriate API; instead, you can just hand your task off to WorkManager and let it choose the best option.
Your requirement comes under Recurring tasks:
Usage is like this:
new PeriodicWorkRequest.Builder photoCheckBuilder =
new PeriodicWorkRequest.Builder(PhotoCheckWorker.class, 12,
TimeUnit.HOURS);
// ...if you want, you can apply constraints to the builder here...
// Create the actual work object:
PeriodicWorkRequest photoCheckWork = photoCheckBuilder.build();
// Then enqueue the recurring task:
WorkManager.getInstance().enqueue(photoCheckWork);

When to use Android Loaders

Loaders
monitor data source and deliver new results
After a configuration change : no need to re-query the data
I read the android guide about Loaders.
I read Alex Lockwood 4 parts tutorial . Tested his sample app too.
Tried to read the Google App for I/O 13, there's a Stream feature and reading its code find out it uses Loaders since it provides code to create a StreamLoader. Here is the Link
I suppose they use it to monitor for new data and add them to their view.
Same for Alex's app. There's an observer and when there is new data entries triggers a refresh for the UI.
So far it seems to me, Loaders are ideal choice for a "livescore" app. When there's a new update ( which means a new data entry ) it appears on your screen.
Maybe something like Twitter. New messages for you, custom Observer to notice for changes, custom Loader brings the data and an adapter to display them. No need to "pull-to-refresh".
But then again Twitter has its own RESTful API which kinda does the same job. No need for a pointer to the new data. ( don't know how they do it but I guess somehow the "push" new data to your device ).
So my question is :
Loaders are best option when we want to observe a data source and change our view so it will display the new data?
Are there any examples/app I can check dealing with that logic : monitor the data source -> get the data -> refresh UI
Any characteristic cases ( like the one with the "livescore" previously mentioned by me ) that when we have to deal with them we have to choose Loaders?
The second part of the Loaders ( configuration change, keeping the data ) I think its clear. No one want's to re-download an Image gallery when the user rotates the device.
Thank you and excuse my confusion
The best way I can describe a Loader is a Handler that is always on. Both Loaders and Handlers pass data between objects.
I agree with what you said about the "livescore" app.
The Loader monitors the source of their data and delivers new results when the content changes.
To answer your questions:
1) Loaders are best option when we want to observe a data source and change our view so it will display the new data?
A: Yes. if your data source is constantly updating. For example, like a stock-ticker app. If your data isn't constantly updating, then no, don't use a loader. For example, if your data source is only retrieved once, then there's no need for a Loader.
2) Are there any examples/app I can check dealing with that logic : monitor the data source -> get the data -> refresh UI
A: https://www.youtube.com/watch?v=3d9BeWqlfTk
Yes, they are what you want to use for the flow you're describing. Tangentially, there's also AsyncTasks and Services that have similarities.
AsyncTasks
Description (from docs):
AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.)
Caution: Another problem you might encounter when using a worker thread is unexpected restarts in your activity due to a runtime configuration change (such as when the user changes the screen orientation), which may destroy your worker thread. To see how you can persist your task during one of these restarts and how to properly cancel the task when the activity is destroyed, see the source code for the Shelves sample application.
If you specifically just want a wrapper to basic threading boilerplate, use an AsyncTask otherwise I'd suggest you use an AsyncTaskLoader if you need a general purpose way to run intensive operations in an Activity or Fragment. You get the same benefits from AsyncTask, but it handles lifecycle issues for you. There are also specialty loaders, such as CursorLoader that will are made to handle specific data sources and have conveniences for interacting with certain UI elements.
Services
Description (from docs):
A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.
You would use a service to handle data being pushed to a phone. Otherwise, the user would have to open your app to get any pushed data. Services do not interact with your UI. So a common design pattern is to use a Service to gather data from a server (whether pushed real time or if you poll) and store it in your database for use both when your app is opened or when not. There are many other use cases for Services, but this one is probably the most popular.
Conclusion
So no, you aren't required to use a Loader to load data or do long running operations on a background thread and pass the results (or progress) to your UI thread, but they are the best option for most use cases.

Categories

Resources