Chapter 4
Chapter 4
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.
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.
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.
onCreate()
onStart()
onResume()
onPause()
onStop()
onRestart()
onDestroy()
1. onCreate()
2. onStart()
3. onResume()
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()
6. onRestart()
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.
Practical Tips
The classes associated with various widgets contain certain public callback methods that can be
used for event handling.
Some of the common callback methods used for event handling include:
onKeyDown(int, KeyEvent)
onKeyUp(int, KeyEvent)
onTrackballEvent(MotionEvent)
onTouchEvent(MotionEvent)
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.
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:
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.
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. 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.
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.
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
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;
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;
@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);
}
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;
}
}
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>
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;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
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();
}
});
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."