A simple and easy to use personal medical notes.
- Easily add your medical notes
- Multiple profile to keep track elderly and family members medical history
- Add medicine information and medicine reminder to notify you to take medicine
- Support dark mode and light mode
This project is intended for demo app for a-navigator and a-provider library usage. The app still works as production even though it is demo app.
The app uses a-navigator framework as navigator and StatefulView as base structure, combined with a-provider library for service locator, and finally RxAndroid to handle UI use cases.
The project is divided into two main modules:
app: Contains the UI logic, navigation, dependency injection wiring, and business logic implementation.base: Contains the Data Layer (Room Entities, DAOs), Repositories, and basic domain models.
The app utilizes a hierarchical provider structure to manage dependency scopes effectively:
- Global Scope (
AppProviderModule):- Lifecycle: Bound to
MainApplication. - Components:
AppDatabase,WorkManager,Notifiers(Singleton),ScheduledExecutorService.
- Lifecycle: Bound to
- Activity Scope (
ActivityProvider):- Lifecycle: Bound to
MainActivity. Created viaProvider.createNestedProvider. - Components:
AppNotificationHandler(UI-specific logic),INavigator(Context-aware).
- Lifecycle: Bound to
- View Scope (
StatefulViewProvider):- Lifecycle: Transient/Pooled.
- Usage: Provides dependencies needed strictly for View rendering or local logic.
- Single Activity:
MainActivityacts as the container. - StatefulView: All pages (e.g.,
HomePage,NotesPage) extendStatefulView. - Configuration:
NavConfigurationmaps String routes (e.g.,/home) toStatefulViewFactoryimplementations. - Back Stack:
Navigatormanages the stack of views.onBackPressedis intercepted and delegated to the Navigator.
- RxJava3 / RxAndroid: Used for all asynchronous operations and event handling.
- RxDisposer: A custom helper class that manages
Disposableobjects.- It is provided via DI and linked to the lifecycle of the Provider/Component.
- When a
StatefulViewis disposed, its associated Provider (and thusRxDisposer) cleans up all active subscriptions, preventing memory leaks.
graph TD
subgraph "Base Module"
DB[(Room Database)]
DAO[DAOs]
Entity[Entities]
end
subgraph "App Module"
subgraph "DI Layer"
AppProv[AppProvider]
ActProv[ActivityProvider]
CmdProv[CommandProvider]
end
subgraph "UI Layer"
Act[MainActivity]
Nav[Navigator]
View["StatefulView (Page)"]
end
subgraph "Logic Layer"
Cmd["Command (Business Logic)"]
Notif["Notifier (Event Bus)"]
end
end
AppProv --> ActProv
Act --> ActProv
ActProv --> Nav
Nav --> View
View -->|Injects| CmdProv
CmdProv -->|Creates| Cmd
Cmd -->|Updates| DAO
DAO -->|Persists| DB
Cmd -->|Triggers| Notif
Notif -->|Emits to| View
The app strictly separates UI from Data Logic using the Command Pattern.
- UI Action: User performs an action (e.g., "Save Note").
- Command Creation: View requests a Command instance (e.g.,
UpdateNoteCmd) fromCommandProvider. - Execution: Command runs on a background thread (
ExecutorService). - Persistence: Command calls
NoteDaoto write to SQLite. - Notification: Upon success, Command calls
NoteChangeNotifier. - Reaction: The Notifier emits an event. Active Views listening to this notifier (via
RxDisposer) update their state.
sequenceDiagram
participant User
participant View as StatefulView
participant Cmd as Command
participant DB as AppDatabase
participant Bus as Notifier
User->>View: Click Save
View->>Cmd: Execute(Data)
activate Cmd
Cmd->>DB: Insert/Update
DB-->>Cmd: Success
Cmd->>Bus: notifyChanged(Data)
deactivate Cmd
Bus-->>View: onNext(Data)
View->>View: updateUI()
The domain follows a strict hierarchy rooted in the Profile.
- Profile: Top-level entity. Represents a person.
- Note: Medical entry. Belongs to a Profile.
- Medicine: Medication details. Belongs to a Note.
- MedicineReminder: Schedule config. Belongs to a Medicine.
- MedicineIntake: History log. Belongs to a Medicine.
erDiagram
PROFILE ||--o{ NOTE : has
NOTE ||--o{ MEDICINE : contains
NOTE ||--o{ NOTE_ATTACHMENT : has
MEDICINE ||--o{ MEDICINE_REMINDER : schedules
MEDICINE ||--o{ MEDICINE_INTAKE : history
Consider donation to support this project
| https://trakteer.id/rh-id |