Designing Entity Classes and Architecture for Small Android Apps
This article shares practical experiences and techniques for Android app development, covering entity class organization, graceful network data handling with Retrofit, robust repository patterns, and clean UI layering using MVVM, DataBinding, and LiveData.
Recently I developed a small, low‑complexity Android app and realized I had never considered architectural concerns, simply coding by habit and ignoring design. This article shares practical experiences and techniques for app development and design.
Organization of Entity Classes
In an Android project many entity classes appear; they can be grouped into three major categories: database‑oriented, server‑response DTOs, and view‑rendering models (used with DataBinding). Typically an entity flows through three steps: request data from server, optionally store it in a database, then render it in the UI.
Using the same entity for all three stages can cause field name conflicts (e.g., both server and local data have an Id field) and type mismatches (numeric data from backend versus string display). Therefore entities should be isolated from each other.
Before rendering, data should be prepared in a ViewModel (e.g., converting integers to strings) and then bound to the UI.
Graceful Handling of Network Data
Most Android projects use Okhttp + Retrofit . A typical server response looks like:
{
"code":0,
"data":{},
"msg":""
}The client focuses on the data field, while msg and code are auxiliary. A generic response class can be defined as:
public class ApiResponse
{
private int code;
private T data;
private String msg;
}With RxJava the service interface becomes:
public interface UserService {
@GET("/xx/{id}")
Single
> getUserInfoById(@Path("id") Long userId);
}To avoid repetitive checks of code and extraction of data , a custom CallAdapter can transform the method to return the data entity directly:
public interface UserService {
@GET("/xx/{id}")
Single
getUserInfoById(@Path("id") Long userId);
}Business‑level errors can be propagated as Java exceptions, e.g., a custom BizException for backend‑defined errors and HttpException for HTTP status failures.
public class BizException extends RuntimeException {
...
}Robust Data Layer
Many apps adopt the MVVM pattern and expose a Repository as the data source. Good repository design follows interface‑driven programming, the single‑responsibility principle, clear functional boundaries, and minimal business logic (delegated to presenters when needed).
A simple base repository can provide service instances:
public class SimpleRepository {
protected final
T getService(Class
clz) {
return Services.getService(clz);
}
}Clean UI Layer
The UI consists of ViewModel and View (Activity/Fragment). Views should only display data and collect user input, delegating validation and business checks to the ViewModel. DataBinding together with LiveData enables automatic UI updates when underlying data changes.
registerViewModel.getRegistryResult().observe(this, new SimpleObserver
(this));If ViewModel logic becomes too complex, consider extracting a Presenter or moving the logic to the backend.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.