Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: What is the smoothest way to synchronize a remote database in the background?

I have an Android database hosted in Parse and I have been trying to find the best way/practices to update my LocalStorage with the latest remote changes.

I'm not asking for code or syntax, I would just be looking for a set of steps to follow, I'm sure I would need to use a worker thread because I don't want to block the UI, I would love to have the transition as smooth as possible for the user (he wouldn't even realise an update is happening) and I want it to happen when the app is on the foreground. The ideas I've gotten so far:

  • Use multithreading (Loopers, Handlers, Thread) and update each table in a separate thread.
  • Try to throttle the request to minimize the CPU usage and get a table at a time.
  • Use a Loader and just listen for the changes.
  • Call an IntentService to get table by table also.
  • Create an Unbound Service and let the database update after the app is closed.
  • Don't update the database in the background and wait until the user actually needs the data and the retrieve it.

I've already tried the IntentService one, it's not as smooth as I would like:

public class DataService extends IntentService {
    public DataService() {
        super(DataService.class.getName());
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String[] entities = {
                "Img",
                "Pack",
                "Technology",
                "Term",
                "TermHierarchy",
                "TermImplementation",
                "TermTerm",
                "UserTechnology",
                "UserTerm",
        };

        for (String entity : entities) {
            updateLocalTable(entity);
        }
    }

    private void updateLocalTable(String entity) {
        ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(entity);
        query.findInBackground(new FindCallback<ParseObject>() {
            @Override
            public void done(List<ParseObject> objects, ParseException e) {
                if (e == null){
                    ParseObject.pinAllInBackground(objects);
                }else {
                    Log.e(TAG_, e.toString());
                }
            }
        });
    }
}

Also, I'm calling it the first time a connection change occur (Wi-Fi available). Should I instead just call it on the onCreate, or create an Alarm to update once every certain amount of time, or just when the Activity is finishing?

I've seen a few post related:

Update data in Background Periodically (Android)

Syncronizing Android client with remote SQL-server database, using web service

Send database data through socket connection

sync remote database (mysql) with sqlite database and vice versa

But none of them have good and detailed answers and they don't really tackle the problem.

I will also add that Parse handles all the RESTful calls and the JSON conversion so I don't have to worry about that.


Edit.

I just found a video that explains these concepts (and supports the answer provided by @gsgsgs) in less than 2 minutes:

https://www.youtube.com/watch?v=Expbi0lHLRE

like image 419
Evin1_ Avatar asked Jan 22 '16 07:01

Evin1_


People also ask

What does offline synchronization do in Android?

Offline sync allows end users to interact with a mobile app—viewing, adding, or modifying data—even when there's no network connection. Changes are stored in a local database. Once the device is back online, these changes are synced with the remote backend.

When should you synchronize databases?

When changes in source database occur, appropriate changes in target db have to be performed. Synchronizer compares records' values at first. Then altered records will be replaced at destination tables in order to establish identity between two tables. As a result of update synchronization all your data keep updated.

What is data Sync in Android?

Synchronizing data between an Android device and web servers can make your application significantly more useful and compelling for your users. For example, transferring data to a web server makes a useful backup, and transferring data from a server makes it available to the user even when the device is offline.


1 Answers

You can try SyncAdapter:

The sync adapter component in your app encapsulates the code for the tasks that transfer data between the device and a server

It's not very simple to implement, but have some advantages:

  • Background sync scheduled by system with other network requests to save battery
  • It can be configured by user in sync settings (disable or enable background sync)
  • Adapter retry sync automatically if request failed with exponential backoff
  • You can simple use it with yours ContentProvider
  • Adapter can sync in a separate process if you want

Here some tutorial.

like image 80
Kirill Avatar answered Dec 14 '22 23:12

Kirill