0% found this document useful (0 votes)
23 views13 pages

Chapter 4

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views13 pages

Chapter 4

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

Chapter 4: Storing and Retrieving Data

Exploring Activity
An activity provides the UI for a single screen in an app.

It provides a distinct visual UI designed around a single, well-defined purpose, for example
dialling a phone number, taking a picture, or sending a message.

An app can have multiple activities and the activity that is presented to the user when an
application is launched is called the main activity.

The Activity class contains lifecycle callback methods for each of these states.

The Activity Lifecycle

During its lifecycle, an activity can exist in one of the following three states:

Running: In this state, the activity is visible to the user on the screen and the user can
interact with the activity.

Paused: In this state, another activity is in the foreground and has the user’s focus, but
this activity is still visible, either because the foreground activity is partially transparent
or does not cover the entire screen.

Stopped: In this state, the activity is completely obscured by another activity and the
activity is now in the background.

The following figure illustrates the life cycle of an activity

Lifecycle Methods
When an activity transitions in and out of its various states, it is notified through various callback
methods contained in the Activity class.

These methods are also called lifecycle methods or lifecycle callback methods.

Some lifecycle callback methods included in the Activity class are:

onCreate()

onStart()

onResume()

onPause()

onStop()

onRestart()

onDestroy()

1. onCreate()

 Called: When the activity is first created.


 Purpose: Used to initialize components like UI, data binding, and data setup. It is where you
usually call setContentView() to define the layout for the activity.
 Example Use: Setting up views, initializing variables, connecting to databases, and retrieving
saved instance states.

2. onStart()

 Called: Just before the activity becomes visible to the user.


 Purpose: Prepares the activity to become visible, usually resuming any paused tasks or
refreshing the UI.
 Example Use: Refreshing UI elements, updating data that may have changed while the activity
was in the background.

3. onResume()

 Called: When the activity starts interacting with the user.


 Purpose: Makes the activity ready to receive user input and actively run, typically resuming
interactions or animations.
 Example Use: Start animations, open exclusive resources (e.g., camera), or reinitialize elements
paused in onPause().
4. onPause()

 Called: When the activity is partially obscured by another activity or the user navigates away.
 Purpose: Pauses ongoing tasks that do not need to continue, such as animations or videos. The
activity is still partially visible but not in the foreground.
 Example Use: Pausing video playback, stopping animations, or releasing lightweight resources.

5. onStop()

 Called: When the activity is no longer visible to the user.


 Purpose: Release resources and complete any final cleanup, as the activity is no longer needed
in the foreground.
 Example Use: Save data, release heavy resources (e.g., database connections), stop network
calls.

6. onRestart()

 Called: Just before the activity restarts, after it was stopped.


 Purpose: Used to reinitialize resources released during onStop().
 Example Use: Reconnect to the database, reapply UI states.

7. onDestroy()

 Called: Before the activity is completely destroyed, either by the user closing it or the system for
resource needs.
 Purpose: Final cleanup and resource release.
 Example Use: Free memory, close open resources.

Lifecycle Flow Diagram

1. First Time: onCreate() → onStart() → onResume()


2. Temporary Interruption (e.g., phone call): onPause() → onResume()
3. Navigating Away: onPause() → onStop()
4. Returning from Background: onRestart() → onStart() → onResume()
5. Finishing Activity: onPause() → onStop() → onDestroy()

Practical Tips

 Save Instance State: Use onSaveInstanceState() to save temporary data.


 Resource Management: Allocate resources in onStart() and release them in onStop() for
efficiency.
 UI Updates: Place essential UI updates in onResume() so they refresh every time the activity
becomes active.

Handling UI Events in the Activity Class


In Android, each widget is associated with various UI events.
You can intercept and handle events in an Android app by using any of the following two
methods:

By using event handlers

By using event listeners

Using Event Handlers

The classes associated with various widgets contain certain public callback methods that can be
used for event handling.

These callback methods are called event handlers.

Some of the common callback methods used for event handling include:

onKeyDown(int, KeyEvent)

onKeyUp(int, KeyEvent)

onTrackballEvent(MotionEvent)

onTouchEvent(MotionEvent)

onFocusChanged(boolean, int, Rect)

Using Event Listeners

The View class provides various interfaces that include a single callback method.

These interfaces are known as event listeners and can be implemented by a class to intercept
events.

Some event listeners include:

View.OnClickListener

View.OnLongClickListener

View.OnFocusChangeListener

View.OnKeyListener

View.OnTouchListener

View.OnCreateContextMenuListener
Synchronization and Replication of Mobile Data

Synchronization and replication of mobile data are essential aspects of Android development,
especially when applications need to function offline or share data across multiple devices.
Here’s an overview of each concept and how they can be implemented in Android apps:

1. Synchronization of Mobile Data

Synchronization is the process of ensuring that data on the mobile device is consistent with data
on a server or in other data sources. It involves checking for updates, handling conflicts, and
transferring data as needed to keep everything up-to-date.

Common Scenarios

 Offline Support: Allows users to access data without an internet connection, then syncs changes
when back online.
 Multi-Device Consistency: Ensures users see the same data across different devices.
 Real-Time Updates: Keeps data consistent for applications where real-time updates are crucial,
like messaging apps.

Strategies for Synchronization

1. Periodic Sync: Syncs at regular intervals or specific triggers, such as a network change
or user action.
o Implementation: Use the JobScheduler API (API 21+) or WorkManager
(recommended for background tasks, as it’s more flexible with constraints).
2. Push Notifications with Firebase Cloud Messaging (FCM): Push notifications can
notify the app when there’s new data to fetch.
o Implementation: Use FCM to send a "data message" that instructs the app to start a
sync job when new data is available.
3. Manual Sync: Provides an option for users to manually sync data (e.g., pull-to-refresh).
o Implementation: Trigger a sync request manually when the user initiates a refresh
action.
4. Sync Adapters (Older Method): This is a built-in Android mechanism for managing
background data synchronization. Although a bit dated, it provides periodic sync by
connecting to the account framework.
o Implementation: Create a SyncAdapter with an authenticator to enable background
syncing tied to specific accounts.
5. Conflict Resolution: Handling conflicts is crucial when data changes on both the device
and the server simultaneously.
o Approaches: Use a Last-Write-Wins strategy, timestamps, or custom merging logic to
resolve conflicts.
2. Replication of Mobile Data

Replication involves creating a local copy of data that is stored on a remote server. This allows
the app to work offline and access data quickly, with changes uploaded when the device is
online.

Common Scenarios

 Offline-First Apps: Apps that store data locally and sync changes to the server.
 High Read Performance: Apps that need quick access to large datasets without constantly
querying a remote database.

Replication Strategies

1. Database Solutions (e.g., SQLite, Room, Realm):


o Use local databases to store a replica of remote data.
o Room (Recommended): Android's Room library provides a lightweight abstraction over
SQLite and allows easy data access with support for LiveData and ViewModel.
o Implementation: Fetch data from a server, save it locally, and sync changes back to the
server when online.
2. Real-Time Database (e.g., Firebase Realtime Database, Firestore):
o Firebase databases provide automatic data synchronization and offline persistence.
o Implementation: Firestore can automatically sync changes between the client and
server, handling offline persistence, making it ideal for real-time and offline-friendly
applications.
3. Custom Sync Logic:
o For more control, implement custom sync mechanisms using Retrofit, WorkManager, or
coroutines to replicate data between a server and local storage.
o Implementation: Fetch data from the API, update the local database, and push changes
back to the server when connectivity is available.

Tools and Libraries for Sync and Replication

1. Room + WorkManager: A popular combination for handling local storage with Room and
background syncing with WorkManager.
2. Firebase Firestore: Handles real-time syncing and offline persistence, ideal for apps requiring
minimal setup and real-time updates.
3. SQLite Database + Custom Network Layer: Retrofit, OkHttp, and Coroutines/LiveData make it
easy to create custom sync solutions.
4. Content Providers (for cross-app sync): If sharing data between multiple apps, content
providers can help sync shared data with access control.
Best Practices for Synchronization and Replication

 Handle Connectivity Changes: Monitor network status to trigger sync when connectivity is
available.
 Efficient Data Management: Avoid overloading the device with unnecessary data by using
pagination, filtering, and delta syncs (only syncing changed data).
 Conflict Management: Implement a robust conflict resolution strategy, especially if multiple
devices can update data simultaneously.
 Data Encryption and Security: Ensure sensitive data is encrypted on the device, and use secure
API communication (HTTPS).
 Optimize Battery Usage: Use WorkManager with constraints to minimize battery consumption
by only syncing when the device is charging or connected to Wi-Fi.

By combining these strategies, Android apps can effectively manage mobile data
synchronization and replication, ensuring smooth user experiences even in scenarios with limited
or intermittent connectivity.

Getting the Model right

In Android app development, “getting the model right” refers to designing a solid and scalable
data model that effectively represents the data structure of your application. A well-designed
model not only makes it easier to manage and access data but also ensures that your app remains
flexible, efficient, and easy to maintain as it scales. Let’s dive into the key principles and steps
involved in designing a robust data model for Android apps.

Key Principles for Getting the Model Right

1. Identify Core Entities and Relationships:


o Define the core objects (entities) in your app and understand how they relate to one
another. For example, in a task management app, entities might include Task, User,
and Project.
o Determine relationships, such as one-to-many (e.g., a User can have multiple Tasks) or
many-to-many (e.g., a Task can belong to multiple Projects).
2. Define Fields and Data Types Carefully:
o Choose appropriate data types for each field (e.g., String for text, int for integers,
boolean for true/false values, long for timestamps).
o Include only relevant fields to avoid clutter and keep the model efficient.
3. Use Proper Data Normalization:
o Normalize your data to avoid redundancy, which can lead to inconsistent data. For
example, rather than storing the same User information in multiple Task records, use a
unique User ID that links tasks to a single user.
4. Plan for Offline Data and Synchronization:
o If your app supports offline access, plan how to store and synchronize data between the
device and a backend server. This usually involves having a local database and managing
when and how data syncs with the server.
5. Consider Future Scalability:
o Design your model with future updates in mind. Avoid tight coupling between entities
so that adding or modifying fields or entities in the future won’t require major changes
to your app’s codebase.

In Android, the Model-View-Controller (MVC) pattern or the Model-View-ViewModel


(MVVM) pattern is typically used, where the Model represents the data structure and business
logic of the application. Using a proper model class that interacts with the SQLite database
ensures that data handling is accurate, isolated, and easy to modify without affecting other parts
of the app.

Android storing and retrieving data

Here's a complete demo for storing and retrieving data in an Android app using Java and SQLite.
In this example, we’ll build a simple app to store and display notes, using SQLite for data
storage.

Project Setup

1. Create a new Android project in Android Studio.


2. Choose Empty Activity and name it NoteApp.

Step 1: Create a Model Class for Notes

This class will represent each note in the app, with properties like id, title, and content.

java
Copy code
// Note.java
public class Note {
private int id;
private String title;
private String content;

public Note(int id, String title, String content) {


this.id = id;
this.title = title;
this.content = content;
}
public int getId() {
return id;
}

public String getTitle() {


return title;
}

public String getContent() {


return content;
}
}

Step 2: Create a Database Helper Class

Create a class that extends SQLiteOpenHelper to manage database creation and version
management.

java
Copy code
// DatabaseHelper.java
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import java.util.ArrayList;
import java.util.List;

public class DatabaseHelper extends SQLiteOpenHelper {

private static final String DATABASE_NAME = "noteDatabase";


private static final int DATABASE_VERSION = 1;

public static final String TABLE_NAME = "notes";


public static final String COLUMN_ID = "id";
public static final String COLUMN_TITLE = "title";
public static final String COLUMN_CONTENT = "content";

public DatabaseHelper(Context context) {


super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + "("
+ COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_TITLE + " TEXT,"
+ COLUMN_CONTENT + " TEXT" + ")";
db.execSQL(createTable);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}

// Insert a new note


public long addNote(String title, String content) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_TITLE, title);
values.put(COLUMN_CONTENT, content);

long id = db.insert(TABLE_NAME, null, values);


db.close();
return id;
}

// Retrieve all notes


public List<Note> getAllNotes() {
List<Note> notes = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();

String selectQuery = "SELECT * FROM " + TABLE_NAME;


Cursor cursor = db.rawQuery(selectQuery, null);

if (cursor.moveToFirst()) {
do {
int id = cursor.getInt(cursor.getColumnIndex(COLUMN_ID));
String title =
cursor.getString(cursor.getColumnIndex(COLUMN_TITLE));
String content =
cursor.getString(cursor.getColumnIndex(COLUMN_CONTENT));
notes.add(new Note(id, title, content));
} while (cursor.moveToNext());
}
cursor.close();
db.close();
return notes;
}
}

Step 3: Design the Layout for Adding and Displaying Notes

In the res/layout folder, create a layout for your main activity (activity_main.xml), which
will contain fields for adding a new note and a list for displaying stored notes.

xml
Copy code
<!-- activity_main.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">

<EditText
android:id="@+id/editTextTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Note Title" />

<EditText
android:id="@+id/editTextContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Note Content"
android:inputType="textMultiLine"
android:minLines="3" />

<Button
android:id="@+id/buttonSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Save Note" />

<TextView
android:id="@+id/textViewNotes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Stored Notes:"
android:textStyle="bold" />

<TextView
android:id="@+id/textViewAllNotes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp" />
</LinearLayout>

Step 4: Implement the Main Activity

Now, add code to save and display notes in MainActivity.java.

java
Copy code
// MainActivity.java
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.List;

public class MainActivity extends AppCompatActivity {


private DatabaseHelper dbHelper;
private EditText editTextTitle, editTextContent;
private TextView textViewAllNotes;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

dbHelper = new DatabaseHelper(this);

editTextTitle = findViewById(R.id.editTextTitle);
editTextContent = findViewById(R.id.editTextContent);
Button buttonSave = findViewById(R.id.buttonSave);
textViewAllNotes = findViewById(R.id.textViewAllNotes);

buttonSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
saveNote();
displayAllNotes();
}
});

displayAllNotes(); // Display notes when the app starts


}

private void saveNote() {


String title = editTextTitle.getText().toString().trim();
String content = editTextContent.getText().toString().trim();

if (!title.isEmpty() && !content.isEmpty()) {


dbHelper.addNote(title, content);
editTextTitle.setText("");
editTextContent.setText("");
}
}

private void displayAllNotes() {


List<Note> notes = dbHelper.getAllNotes();
StringBuilder noteText = new StringBuilder();

for (Note note : notes) {


noteText.append("ID: ").append(note.getId()).append("\n")
.append("Title: ").append(note.getTitle()).append("\n")
.append("Content:
").append(note.getContent()).append("\n\n");
}

textViewAllNotes.setText(noteText.toString());
}
}
Step 5: Run the App

1. Connect an emulator or device and run the app from Android Studio.
2. Enter a title and content for a note, then tap Save Note.
3. The saved note should display under "Stored Notes."

You might also like