Open In App

Synchronization in Android with Example

Last Updated : 06 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In Android, synchronization refers to the process of ensuring that data stored in multiple locations is the same and up-to-date. This can be achieved through various methods such as using the built-in Android synchronization adapters, or by manually implementing synchronization using the Android Sync Framework. Additionally, Android also provides APIs for synchronizing data with cloud-based services such as Google Drive and Dropbox.

Using the built-in Android synchronization adapters in Java and Kotlin

Kotlin




val syncRequest = SyncRequest.Builder()
    .syncPeriodic(SYNC_INTERVAL, SYNC_FLEXTIME)
    .setSyncAdapter(account, AUTHORITY)
    .setExtras(Bundle.EMPTY)
    .build()
ContentResolver.requestSync(syncRequest)


Java




// Define a new account type and account
Account newAccount = new Account("example", ACCOUNT_TYPE);
  
// Add the account and account type to the Android Account Manager
AccountManager accountManager = (AccountManager) getSystemService(ACCOUNT_SERVICE);
accountManager.addAccountExplicitly(newAccount, null, null);
  
// Pass the account and authority to a new ContentResolver sync request
ContentResolver.setSyncAutomatically(newAccount, AUTHORITY, true);
ContentResolver.addPeriodicSync(newAccount, AUTHORITY, Bundle.EMPTY, SYNC_INTERVAL);


In these examples,

The AUTHORITY variable would be a string that represents the authority of the content provider that is being synced, and the SYNC_INTERVAL variable would be an integer representing the number of seconds between sync attempts.

Advantages of synchronization in Android include:

  • Data consistency: By synchronizing data between multiple locations, you can ensure that the data is the same and up-to-date everywhere it is stored.
  • Improved user experience: Synchronization can improve the user experience by ensuring that data is quickly and easily accessible, even when the device is offline.
  • Cloud integration: Android provides APIs for synchronizing data with cloud-based services, which allows for easy data backup and sharing.
  • Automation: The built-in Android synchronization adapters can automatically handle the process of synchronizing data, which can save time and reduce the potential for errors.

Synchronization is an important aspect of Android development, it ensures data consistency, improves user experience, and allows data backup and sharing with cloud integration. Using the built-in Android synchronization adapters can automate this process and make it easy to implement.

Step-by-Step Implementation

Step 1: Create a New Project in Android Studio

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. The code for that has been given in both Java and Kotlin Programming Language for Android.

Step 2: Working with the XML Files

Next, go to the activity_main.xml file, which represents the UI of the project. Below is the code for the activity_main.xml file. Comments are added inside the code to understand the code in more detail.

XML




<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
  
    <!-- A text view to display the count -->
    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0"
        android:textSize="32sp"
        app:layout_constraintBottom_toTopOf="@+id/increment_button"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
  
    <!-- A button to increment the count -->
    <Button
        android:id="@+id/increment_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="incrementCounter"
        android:text="Increment"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    
</androidx.constraintlayout.widget.ConstraintLayout>


Step 3: Working with the MainActivity & ExampleIntentService File

Go to the MainActivity File and refer to the following code. Below is the code for the MainActivity File. Comments are added inside the code to understand the code in more detail.

Kotlin




import android.os.Bundle
import android.os.Handler
import android.util.Log
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import java.util.concurrent.Semaphore
  
class MainActivity : AppCompatActivity() {
      
    private var counter = 0
    private lateinit var textView: TextView
  
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
          
        // Get the reference to the 
        // text view from the layout
        textView = findViewById(R.id.text_view)
    }
  
    // The incrementCounter method is invoked 
    // when the "Increment" button is clicked.
    fun incrementCounter(view: View?) {
        Thread {
            try {
                // Acquiring the semaphore lock
                semaphore.acquire()
                synchronized(lock) {
                    // Incrementing the counter value
                    counter++
                }
            } catch (e: InterruptedException) {
                Log.e(TAG, "Thread interrupted", e)
            } finally {
                // Releasing the semaphore lock
                semaphore.release()
            }
            // Updating the text view on the UI thread
            updateTextView()
        }.start()
    }
  
    // The updateTextView method updates the text view
    // with the current counter value.
    private fun updateTextView() {
        // Posting the text view update
        // task on the UI thread
        Handler(mainLooper).post {
            textView.text = counter.toString()
        }
    }
  
    companion object {
        private const val TAG = "MainActivity"
        // The lock object used for synchronizing 
        // the access to the counter value.
        private val lock = Any()
        private const val MAX_THREADS = 5
          
        // The semaphore used to limit the number of 
        // concurrent threads accessing the counter value.
        private val semaphore = Semaphore(MAX_THREADS)
    }
}


Java




import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.concurrent.Semaphore;
  
public class MainActivity extends AppCompatActivity {
    // TAG used for logging purposes
    private static final String TAG = "MainActivity";
      
    // Object used for synchronizing access to counter
    private static final Object lock = new Object();
      
    // Maximum number of concurrent threads
    // that can access the counter
    private static final int MAX_THREADS = 5;
      
    // Semaphore to limit concurrent access to the counter
    private static final Semaphore semaphore = new Semaphore(MAX_THREADS);
      
    // Counter to store the 
    // number of button clicks
    private int counter = 0;
      
    // Reference to the text view to 
    // display the number of button clicks
    private TextView textView;
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Get the reference to the 
        // text view from the layout
        textView = findViewById(R.id.text_view);
    }
  
    // Method called when the button is clicked
    public void incrementCounter(View view) {
        // Start a new thread to increment the counter
        new Thread(() -> {
            try {
                // Acquire the semaphore
                semaphore.acquire();
                // Synchronized block to update the counter
                synchronized (lock) {
                    counter++;
                }
            } catch (InterruptedException e) {
                // Log an error if the thread is interrupted
                Log.e(TAG, "Thread interrupted", e);
            } finally {
                // Release the semaphore
                semaphore.release();
            }
            // Update the text view on the main thread
            updateTextView();
        }).start();
    }
  
    // Method to update the text view on the main thread
    private void updateTextView() {
        // Post the update to the main thread's message queue
        new Handler(getMainLooper()).post(() -> textView.setText(String.valueOf(counter)));
    }
}


Output:

 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads