mad-pro-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +17 -0
- package/lib/commands/init.js +42 -0
- package/package.json +26 -0
- package/templates/mad-skills/SKILL.md +77 -0
- package/templates/mad-skills/references/accessibility.md +63 -0
- package/templates/mad-skills/references/adaptive_layouts.md +51 -0
- package/templates/mad-skills/references/advanced_performance.md +52 -0
- package/templates/mad-skills/references/advanced_ui.md +64 -0
- package/templates/mad-skills/references/ai_ml.md +38 -0
- package/templates/mad-skills/references/architecture_di.md +63 -0
- package/templates/mad-skills/references/automation_cicd.md +53 -0
- package/templates/mad-skills/references/clean_architecture.md +80 -0
- package/templates/mad-skills/references/cmp_migration.md +56 -0
- package/templates/mad-skills/references/concurrency.md +50 -0
- package/templates/mad-skills/references/deeplinks.md +42 -0
- package/templates/mad-skills/references/design_principles.md +47 -0
- package/templates/mad-skills/references/design_systems.md +47 -0
- package/templates/mad-skills/references/domain_layer.md +47 -0
- package/templates/mad-skills/references/google_play_skills.md +40 -0
- package/templates/mad-skills/references/kmp_migration.md +62 -0
- package/templates/mad-skills/references/layouts.md +57 -0
- package/templates/mad-skills/references/local_data.md +53 -0
- package/templates/mad-skills/references/migration_xml_to_compose.md +80 -0
- package/templates/mad-skills/references/modifiers.md +46 -0
- package/templates/mad-skills/references/modularization.md +70 -0
- package/templates/mad-skills/references/multiplatform.md +55 -0
- package/templates/mad-skills/references/navigation.md +48 -0
- package/templates/mad-skills/references/network_data.md +87 -0
- package/templates/mad-skills/references/observability.md +46 -0
- package/templates/mad-skills/references/performance.md +51 -0
- package/templates/mad-skills/references/security.md +67 -0
- package/templates/mad-skills/references/solid_principles.md +61 -0
- package/templates/mad-skills/references/state_management.md +46 -0
- package/templates/mad-skills/references/testing.md +48 -0
- package/templates/mad-skills/references/theming.md +52 -0
- package/templates/mad-skills/references/ui_patterns.md +80 -0
- package/templates/mad-skills/references/workmanager.md +55 -0
package/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { program } from 'commander';
|
|
4
|
+
import initCommand from './lib/commands/init.js';
|
|
5
|
+
|
|
6
|
+
program
|
|
7
|
+
.name('mad-pro')
|
|
8
|
+
.description('MAD Pro CLI - Boost your project with AI Expert Skills')
|
|
9
|
+
.version('1.0.0');
|
|
10
|
+
|
|
11
|
+
program
|
|
12
|
+
.command('init')
|
|
13
|
+
.description('Initialize AI skills for your project')
|
|
14
|
+
.option('--ai <name>', 'Specify the AI bridge to use (e.g., antigravity)')
|
|
15
|
+
.action(initCommand);
|
|
16
|
+
|
|
17
|
+
program.parse();
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = path.dirname(__filename);
|
|
8
|
+
|
|
9
|
+
export default async function initCommand(options) {
|
|
10
|
+
const targetDir = process.cwd();
|
|
11
|
+
const aiName = options.ai || 'antigravity';
|
|
12
|
+
|
|
13
|
+
console.log(chalk.blue(`Initializing project with ${aiName} skills...`));
|
|
14
|
+
|
|
15
|
+
if (aiName === 'antigravity') {
|
|
16
|
+
try {
|
|
17
|
+
// In a published package, templates are bundled inside the package folder
|
|
18
|
+
const sourceSkillsPath = path.resolve(__dirname, '../../templates/mad-skills');
|
|
19
|
+
const destinationPath = path.join(targetDir, '.agent', 'skills', 'mad-skills');
|
|
20
|
+
|
|
21
|
+
console.log(chalk.yellow(`Installing skills to ${destinationPath}...`));
|
|
22
|
+
|
|
23
|
+
await fs.ensureDir(destinationPath);
|
|
24
|
+
|
|
25
|
+
// Copy SKILL.md
|
|
26
|
+
await fs.copy(path.join(sourceSkillsPath, 'SKILL.md'), path.join(destinationPath, 'SKILL.md'));
|
|
27
|
+
|
|
28
|
+
// Copy references directory
|
|
29
|
+
await fs.copy(path.join(sourceSkillsPath, 'references'), path.join(destinationPath, 'references'));
|
|
30
|
+
|
|
31
|
+
console.log(chalk.green('\n✅ Success! MAD Skills (Antigravity Bridge) installed.'));
|
|
32
|
+
console.log(chalk.cyan(`\nYour AI agent (Antigravity) can now find these skills at: ${destinationPath}`));
|
|
33
|
+
console.log(chalk.gray('\nTo use these skills, make sure your agent is instructed to read the .agent/skills directory.'));
|
|
34
|
+
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.error(chalk.red('\n❌ Error installing skills:'), error.message);
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
console.log(chalk.red(`\n❌ Unknown AI bridge: ${aiName}`));
|
|
40
|
+
console.log(chalk.gray('Available bridges: antigravity'));
|
|
41
|
+
}
|
|
42
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mad-pro-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"mad-pro": "./index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"index.js",
|
|
11
|
+
"lib",
|
|
12
|
+
"templates"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [],
|
|
18
|
+
"author": "",
|
|
19
|
+
"license": "ISC",
|
|
20
|
+
"description": "",
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"chalk": "^5.6.2",
|
|
23
|
+
"commander": "^14.0.3",
|
|
24
|
+
"fs-extra": "^11.3.4"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Modern Android Development (MAD) Skills
|
|
3
|
+
description: Expert guidance for building robust, scalable, and maintainable Android applications using Modern Android Development (MAD) principles.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Modern Android Development (MAD) Skills
|
|
7
|
+
|
|
8
|
+
You are an expert Android developer specializing in Modern Android Development (MAD). Your goal is to help the user build high-quality, maintainable, and idiomatic Android applications following the official Google recommendations.
|
|
9
|
+
|
|
10
|
+
Follow these core principles:
|
|
11
|
+
|
|
12
|
+
1. **Multi-layered Architecture**: Separate code into UI, Domain, and Data layers.
|
|
13
|
+
2. **Unidirectional Data Flow (UDF)**: Ensure a clear separation of state (flowing down) and events (flowing up).
|
|
14
|
+
3. **Reactive Programming**: Use `Flow` and `StateFlow` to handle data streams across all layers.
|
|
15
|
+
4. **Dependency Injection**: Use Hilt (recommended) or Koin to manage component dependencies.
|
|
16
|
+
5. **Modern UI**: Use Jetpack Compose and Material 3 for all new features.
|
|
17
|
+
|
|
18
|
+
## Architecture Layers
|
|
19
|
+
|
|
20
|
+
### 1. UI Layer
|
|
21
|
+
|
|
22
|
+
- **[State Management](references/state_management.md)**: `UiState` patterns, ViewModels, and `collectAsStateWithLifecycle`.
|
|
23
|
+
- **[UI Patterns](references/ui_patterns.md)**: Slot APIs and reusable components.
|
|
24
|
+
- **[Layouts & Structure](references/layouts.md)**: Building responsive UI with `Scaffold` and Material 3.
|
|
25
|
+
- **[Modifiers](references/modifiers.md)**: Chaining, ordering, and best practices.
|
|
26
|
+
- **[Theming](references/theming.md)**: Material 3, typography, and Dynamic Color.
|
|
27
|
+
- **[Navigation](references/navigation.md)**: Type-safe navigation.
|
|
28
|
+
|
|
29
|
+
### 2. Domain Layer
|
|
30
|
+
|
|
31
|
+
- **[Domain Layer](references/domain_layer.md)**: Use Cases and business logic isolation.
|
|
32
|
+
|
|
33
|
+
### 3. Data Layer
|
|
34
|
+
|
|
35
|
+
- **[Data Layer & Room](references/local_data.md)**: Offline-first with Room and DataStore.
|
|
36
|
+
- **[Networking](references/network_data.md)**: Retrofit/Ktor, JSON serialization, and error handling.
|
|
37
|
+
|
|
38
|
+
## Utilities & Specialized Skills
|
|
39
|
+
|
|
40
|
+
- **[Architecture & DI](references/architecture_di.md)**: Orchestrating layers with Hilt and Koin.
|
|
41
|
+
- **[Concurrency & Flow](references/concurrency.md)**: Coroutines and Flows across the stack.
|
|
42
|
+
- **[Performance](references/performance.md)**: Stability and recomposition optimization.
|
|
43
|
+
- **[Testing](references/testing.md)**: Semantic UI tests and Unit testing.
|
|
44
|
+
- **[Security](references/security.md)**: Secure storage, biometrics, and permissions.
|
|
45
|
+
- **[Advanced UI (Pro)](references/advanced_ui.md)**: Animations, Canvas, and custom layouts.
|
|
46
|
+
- **[accessibility](references/accessibility.md)**: Inclusivity and Semantics.
|
|
47
|
+
- **[Google Play Skills](references/google_play_skills.md)**: Compliance and release management.
|
|
48
|
+
- **[WorkManager](references/workmanager.md)**: Persistent and reliable background tasks.
|
|
49
|
+
|
|
50
|
+
### 4. Advanced & Ecosystem Skills
|
|
51
|
+
|
|
52
|
+
- **[Modularization](references/modularization.md)**: Multi-module architecture and Version Catalogs.
|
|
53
|
+
- **[KMP & Multiplatform](references/multiplatform.md)**: Logic sharing and Compose Multiplatform.
|
|
54
|
+
- **[Adaptive UI](references/adaptive_layouts.md)**: Large screens, foldables, and Window Size Classes.
|
|
55
|
+
- **[Observability & Health](references/observability.md)**: Crashlytics, Remote Config, and Monitoring.
|
|
56
|
+
- **[Advanced Performance](references/advanced_performance.md)**: Baseline Profiles and Macrobenchmarking.
|
|
57
|
+
- **[Deep Links](references/deeplinks.md)**: App Links and verified navigation.
|
|
58
|
+
- **[On-Device AI](references/ai_ml.md)**: Gemini Nano and ML Kit integration.
|
|
59
|
+
|
|
60
|
+
### 5. Engineering Excellence
|
|
61
|
+
|
|
62
|
+
- **[Clean Architecture](references/clean_architecture.md)**: Layers, dependency rule, and MAD mapping.
|
|
63
|
+
- **[SOLID Principles](references/solid_principles.md)**: Sustainable software design with Android examples.
|
|
64
|
+
- **[Design Systems](references/design_systems.md)**: Professional tokens and shared components at scale.
|
|
65
|
+
|
|
66
|
+
### 6. Platform Evolution & Migration
|
|
67
|
+
|
|
68
|
+
- **[XML to Compose](references/migration_xml_to_compose.md)**: Gradual UI modernization.
|
|
69
|
+
- **[Android to KMP](references/kmp_migration.md)**: Sharing logic across platforms.
|
|
70
|
+
- **[Compose to CMP](references/cmp_migration.md)**: Sharing UI across platforms.
|
|
71
|
+
- **[Automation & CI/CD](references/automation_cicd.md)**: GitHub Actions and Fastlane pipelines.
|
|
72
|
+
|
|
73
|
+
## Code Style
|
|
74
|
+
|
|
75
|
+
- Use trailing commas for all composable parameters.
|
|
76
|
+
- Order parameters: `Modifier` first (if not required), then functional parameters last.
|
|
77
|
+
- Naming: UI state classes should end in `UiState`. Events should end in `UiEvent`.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Accessibility in Jetpack Compose
|
|
2
|
+
|
|
3
|
+
Creating inclusive apps is a core responsibility. Compose provides a powerful "Semantics" system to make your UI accessible to everyone.
|
|
4
|
+
|
|
5
|
+
## 1. Content Descriptions
|
|
6
|
+
|
|
7
|
+
The most basic step. Always provide a `contentDescription` for purely visual elements like `Icon` or `Image` unless they are decorative.
|
|
8
|
+
|
|
9
|
+
```kotlin
|
|
10
|
+
Icon(
|
|
11
|
+
imageVector = Icons.Default.Add,
|
|
12
|
+
contentDescription = "Add new contact" // Specific action
|
|
13
|
+
)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## 2. Using Semantics
|
|
17
|
+
|
|
18
|
+
Use the `Modifier.semantics` for complex components where the default behavior isn't enough.
|
|
19
|
+
|
|
20
|
+
- **`mergeDescendants = true`**: Groups smaller elements into a single focusable entity for screen readers.
|
|
21
|
+
- **`heading()`**: Marks a component as a header to help users navigate.
|
|
22
|
+
- **`stateDescription`**: Provides a custom description for a state (e.g., "Active" instead of just "Checked").
|
|
23
|
+
|
|
24
|
+
```kotlin
|
|
25
|
+
Column(
|
|
26
|
+
modifier = Modifier
|
|
27
|
+
.semantics(mergeDescendants = true) {
|
|
28
|
+
heading()
|
|
29
|
+
}
|
|
30
|
+
) {
|
|
31
|
+
Text("User Profile")
|
|
32
|
+
Text("John Doe")
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 3. Custom Actions
|
|
37
|
+
|
|
38
|
+
Use `onClickLabel` to specify what happens when an item is clicked, which is read by TalkBack.
|
|
39
|
+
|
|
40
|
+
```kotlin
|
|
41
|
+
Modifier.clickable(
|
|
42
|
+
onClickLabel = "Open detailed profile",
|
|
43
|
+
onClick = { ... }
|
|
44
|
+
)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 4. Visual Accessibility
|
|
48
|
+
|
|
49
|
+
- **Touch Targets**: Ensure all interactive elements are at least **48x48dp**.
|
|
50
|
+
- **Dynamic Type**: Use `sp` for text sizes to ensure they scale with the user's system font settings.
|
|
51
|
+
- **Contrast**: Use Material 3 theme colors to ensure proper contrast ratios.
|
|
52
|
+
|
|
53
|
+
- **TalkBack**: Test your app manually with TalkBack enabled.
|
|
54
|
+
- **Accessibility Scanner**: Use the Google Accessibility Scanner app to identify common issues.
|
|
55
|
+
- **Semantic Assertions in Tests**:
|
|
56
|
+
|
|
57
|
+
## 5. Testing Accessibility
|
|
58
|
+
|
|
59
|
+
```kotlin
|
|
60
|
+
composeTestRule
|
|
61
|
+
.onNode(hasContentDescription("Add"))
|
|
62
|
+
.assertExists()
|
|
63
|
+
```
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Adaptive Layouts and Large Screens
|
|
2
|
+
|
|
3
|
+
Modern Android apps must provide a great experience across all form factors: phones, foldables, tablets, and desktop.
|
|
4
|
+
|
|
5
|
+
## 1. Window Size Classes
|
|
6
|
+
|
|
7
|
+
Instead of targeting specific pixel widths, use Window Size Classes to categorize screen sizes:
|
|
8
|
+
|
|
9
|
+
- **Compact**: Typical phone in portrait.
|
|
10
|
+
- **Medium**: Small tablets, large foldables, or landscape phones.
|
|
11
|
+
- **Expanded**: Large tablets and desktop.
|
|
12
|
+
|
|
13
|
+
```kotlin
|
|
14
|
+
@Composable
|
|
15
|
+
fun MyApp(windowSize: WindowSizeClass) {
|
|
16
|
+
when (windowSize.widthSizeClass) {
|
|
17
|
+
WindowWidthSizeClass.Compact -> MyCompactUI()
|
|
18
|
+
WindowWidthSizeClass.Medium -> MyMediumUI()
|
|
19
|
+
WindowWidthSizeClass.Expanded -> MyExpandedUI()
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 2. Canonical Layout Patterns
|
|
25
|
+
|
|
26
|
+
Google recommends three standard patterns for large screens:
|
|
27
|
+
|
|
28
|
+
- **List-Detail**: Best for browsing content while keeping context (e.g., Email, Messaging).
|
|
29
|
+
- **Supporting Pane**: Main content with a side pane for secondary info (e.g., Documents with comments).
|
|
30
|
+
- **Feed**: Grids that expand or stack based on width (e.g., Social Media, Photo Gallery).
|
|
31
|
+
|
|
32
|
+
## 3. Navigation Components for Adaptive UI
|
|
33
|
+
|
|
34
|
+
- **Bottom Navigation**: Use for Compact (phone) screens.
|
|
35
|
+
- **Navigation Rail**: Use for Medium (tablet) screens.
|
|
36
|
+
- **Navigation Drawer**: Use for Expanded (large tablet/desktop) screens.
|
|
37
|
+
|
|
38
|
+
## 4. Handling Foldables
|
|
39
|
+
|
|
40
|
+
Use the **Jetpack WindowManager** library to detect folding states:
|
|
41
|
+
|
|
42
|
+
- **Tabletop Mode**: Half of the screen on a flat surface.
|
|
43
|
+
- **Book Mode**: Half-folded vertically.
|
|
44
|
+
|
|
45
|
+
Ensure content avoids the "hinge" area when the device is not flat.
|
|
46
|
+
|
|
47
|
+
## 5. Testing Adaptive UI
|
|
48
|
+
|
|
49
|
+
- Use **Resizing Emulators** in Android Studio.
|
|
50
|
+
- Run UI tests with different configuration overrides.
|
|
51
|
+
- Use **Screenshot Testing** to verify layouts across different size classes.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Advanced Performance Tools
|
|
2
|
+
|
|
3
|
+
While standard performance optimization focuses on code efficiency, advanced tools help you optimize the "experience" of the app (startup, smoothness, battery).
|
|
4
|
+
|
|
5
|
+
## 1. Baseline Profiles
|
|
6
|
+
|
|
7
|
+
Baseline Profiles tell the Android Runtime (ART) which methods should be pre-compiled to machine code. This can improve app startup time and smooth scrolling by up to 30%.
|
|
8
|
+
|
|
9
|
+
- **Generate**: Use the Benchmark library to record a "warmup profile".
|
|
10
|
+
- **Distribute**: Include the profile in your AAB (Android App Bundle).
|
|
11
|
+
|
|
12
|
+
## 2. Macrobenchmark Library
|
|
13
|
+
|
|
14
|
+
Use Macrobenchmark to measure large-scale interactions:
|
|
15
|
+
|
|
16
|
+
- **Startup Timing**: Cold, Warm, and Hot startup measurements.
|
|
17
|
+
- **Frame Timing**: Measure jank during scrolling or complex animations.
|
|
18
|
+
|
|
19
|
+
```kotlin
|
|
20
|
+
@RunWith(AndroidJUnit4::class)
|
|
21
|
+
class StartupBenchmark {
|
|
22
|
+
@get:Rule
|
|
23
|
+
val benchmarkRule = MacrobenchmarkRule()
|
|
24
|
+
|
|
25
|
+
@Test
|
|
26
|
+
fun startup() = benchmarkRule.measureRepeated(
|
|
27
|
+
packageName = "com.example.myapp",
|
|
28
|
+
metrics = listOf(StartupTimingMetric()),
|
|
29
|
+
iterations = 5,
|
|
30
|
+
startupMode = StartupMode.COLD
|
|
31
|
+
) {
|
|
32
|
+
pressHome()
|
|
33
|
+
startActivityAndWait()
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 3. App Startup Library
|
|
39
|
+
|
|
40
|
+
The App Startup library provides a straightforward, performant way to initialize components at application startup. Use this instead of multiple `ContentProviders`, which slow down the app launch.
|
|
41
|
+
|
|
42
|
+
## 4. Layout Inspector and Validation
|
|
43
|
+
|
|
44
|
+
- **Live Edit**: See changes in real-time without building.
|
|
45
|
+
- **Recomposition Counter**: Identify "dirty" components that recompose too often.
|
|
46
|
+
- **Color Blindness Check**: Verify UI contrast and accessibility colors.
|
|
47
|
+
|
|
48
|
+
## 5. APK Size Optimization
|
|
49
|
+
|
|
50
|
+
- **R8/ProGuard**: Shrink, obfuscate, and optimize your code.
|
|
51
|
+
- **Resource Shrinking**: Remove unused resources automatically.
|
|
52
|
+
- **Dynamic Delivery**: Only deliver code/resources needed for the specific device configuration.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Advanced UI & Pro Techniques in Compose
|
|
2
|
+
|
|
3
|
+
Take your Compose skills to the next level with complex animations, custom drawing, and specialized layouts.
|
|
4
|
+
|
|
5
|
+
## 1. Advanced Animations
|
|
6
|
+
|
|
7
|
+
Move beyond `AnimatedVisibility` to more fine-grained control.
|
|
8
|
+
|
|
9
|
+
### `updateTransition`
|
|
10
|
+
|
|
11
|
+
Manage multiple animation properties simultaneously that are linked to a single state change.
|
|
12
|
+
|
|
13
|
+
```kotlin
|
|
14
|
+
val transition = updateTransition(expanded, label = "cardExpansion")
|
|
15
|
+
val color by transition.animateColor { isExpanded -> if (isExpanded) Red else Blue }
|
|
16
|
+
val size by transition.animateDp { isExpanded -> if (isExpanded) 200.dp else 100.dp }
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### `Animatable`
|
|
20
|
+
|
|
21
|
+
For low-level, fire-and-forget animations or animations where you need a custom listener/trigger.
|
|
22
|
+
|
|
23
|
+
```kotlin
|
|
24
|
+
val alpha = remember { Animatable(0f) }
|
|
25
|
+
LaunchedEffect(Unit) {
|
|
26
|
+
alpha.animateTo(1f, animationSpec = tween(1000))
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 2. Custom Drawing with Canvas
|
|
31
|
+
|
|
32
|
+
When standard components aren't enough, use the `Canvas` API.
|
|
33
|
+
|
|
34
|
+
- **Draw Phase**: Drawing is highly efficient because it bypasses Layout and Composition.
|
|
35
|
+
- **Access to Native Canvas**: You can drop down to `drawIntoCanvas` to use standard Android `android.graphics.Canvas` features.
|
|
36
|
+
|
|
37
|
+
```kotlin
|
|
38
|
+
Canvas(modifier = Modifier.size(100.dp)) {
|
|
39
|
+
drawCircle(color = Color.Blue, radius = size.minDimension / 2)
|
|
40
|
+
drawLine(color = Color.Black, start = Offset.Zero, end = Offset(size.width, size.height))
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 3. Custom Layouts
|
|
45
|
+
|
|
46
|
+
If `Row`, `Column`, and `Box` don't fit your needs, build a custom layout.
|
|
47
|
+
|
|
48
|
+
- **`Layout` composable**: Measure children once, and place them in a 2D space.
|
|
49
|
+
- **`SubcomposeLayout`**: Allows you to defer composition of some children until you know the constraints of others (used in `Scaffold` and `BoxWithConstraints`).
|
|
50
|
+
|
|
51
|
+
## 4. Advanced Interactivity
|
|
52
|
+
|
|
53
|
+
- **`PointerInput`**: Detect custom gestures like multi-touch, long-press with specific offsets, or custom drag-and-drop.
|
|
54
|
+
- **LookaheadScope**: New in Compose, allows you to "look ahead" at where a layout *will* be to animate transitions smoothly between different layout configurations.
|
|
55
|
+
|
|
56
|
+
## 5. Visual Effects
|
|
57
|
+
|
|
58
|
+
- **`graphicsLayer`**: Applying renders effects like `blur`, `shadow`, `scale`, and `rotation` efficiently.
|
|
59
|
+
- **Shaders**: Use `RuntimeShader` (Android AGSL) to create high-performance visual effects like glows, patterns, and distortions.
|
|
60
|
+
|
|
61
|
+
## 6. Performance "Pro" Tips
|
|
62
|
+
|
|
63
|
+
- **Avoid frequent state reads in Composition**: If a value changes 60 times per second, read it only in the **Draw** or **Layout** phase using lambda modifiers.
|
|
64
|
+
- **Stability Monitoring**: Use the `compose-compiler-report` to identify unstable classes that are causing excessive recomposition.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# On-Device AI in Modern Android
|
|
2
|
+
|
|
3
|
+
Integrating AI directly on the device ensures privacy, works offline, and reduces latency.
|
|
4
|
+
|
|
5
|
+
## 1. Google AI Edge SDK
|
|
6
|
+
|
|
7
|
+
The Google AI Edge SDK provides access to **Gemini Nano**, the smallest and most efficient model designed for on-device tasks.
|
|
8
|
+
|
|
9
|
+
### Use Cases
|
|
10
|
+
|
|
11
|
+
- **Summarization**: Summarizing long texts locally.
|
|
12
|
+
- **Smart Reply**: Generating context-aware reply suggestions.
|
|
13
|
+
- **Content safety**: Local filtering of sensitive content.
|
|
14
|
+
|
|
15
|
+
## 2. ML Kit
|
|
16
|
+
|
|
17
|
+
For specialized vision and NLP tasks, use ML Kit.
|
|
18
|
+
|
|
19
|
+
- **Vision APIs**: Barcode scanning, Face detection, Object detection, OCR (Text Recognition).
|
|
20
|
+
- **Natural Language APIs**: Language identification, Translation (offline), Smart Reply.
|
|
21
|
+
|
|
22
|
+
## 3. Implementation Patterns
|
|
23
|
+
|
|
24
|
+
Always handle AI operations asynchronously using Coroutines and monitor battery/thermal impact.
|
|
25
|
+
|
|
26
|
+
```kotlin
|
|
27
|
+
// Example: Text Recognition with ML Kit
|
|
28
|
+
suspend fun recognizeText(image: InputImage): String {
|
|
29
|
+
val recognizer = TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS)
|
|
30
|
+
return recognizer.process(image).await().text
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 4. Best Practices
|
|
35
|
+
|
|
36
|
+
- **Fallback Strategy**: Always have a non-AI or cloud-based fallback if the device model is not supported.
|
|
37
|
+
- **Model Management**: Download models only when needed (on Wi-Fi) to save user data.
|
|
38
|
+
- **Privacy First**: Explicitly inform users when data is processed locally vs. in the cloud.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Architecture and Dependency Injection in Modern Android Development
|
|
2
|
+
|
|
3
|
+
Modern Android Development (MAD) follows a multi-layered architecture to ensure separation of concerns, scalability, and testability.
|
|
4
|
+
|
|
5
|
+
## 1. The MAD Layered Architecture
|
|
6
|
+
|
|
7
|
+
### UI Layer
|
|
8
|
+
|
|
9
|
+
- **Composables**: Pure, stateless UI components.
|
|
10
|
+
- **ViewModels**: Manage UI state and handle user events. ViewModels interact with the Domain Layer (Use Cases) or the Data Layer (Repositories).
|
|
11
|
+
|
|
12
|
+
### Domain Layer (Optional)
|
|
13
|
+
|
|
14
|
+
- **Use Cases**: Encapsulate complex business logic and enable reusability across ViewModels.
|
|
15
|
+
- **Domain Models**: Pure Kotlin classes representing the data used by the business logic.
|
|
16
|
+
|
|
17
|
+
### Data Layer
|
|
18
|
+
|
|
19
|
+
- **Repositories**: Orchestrate data from multiple sources (Network, Local DB, Cache) and provide a clean API to the other layers.
|
|
20
|
+
- **Data Sources**: Implementation details like Retrofit services (Network) or Room DAOs (Local).
|
|
21
|
+
|
|
22
|
+
## 2. Unidirectional Data Flow (UDF)
|
|
23
|
+
|
|
24
|
+
Data should flow in a single direction to maintain a predictable state:
|
|
25
|
+
|
|
26
|
+
1. **State Flows Down**: Data travels from Repositories -> Use Cases -> ViewModels -> UI.
|
|
27
|
+
2. **Events Flow Up**: User interactions travel from UI -> ViewModels -> Use Cases -> Repositories.
|
|
28
|
+
|
|
29
|
+
Managing dependencies manually leads to tightly coupled code. Use DI frameworks to automate this.
|
|
30
|
+
|
|
31
|
+
### Hilt (Recommended)
|
|
32
|
+
|
|
33
|
+
Google's official wrapper around Dagger, optimized for Android.
|
|
34
|
+
|
|
35
|
+
**ViewModel Injection:**
|
|
36
|
+
|
|
37
|
+
```kotlin
|
|
38
|
+
@HiltViewModel
|
|
39
|
+
class UserViewModel @Inject constructor(
|
|
40
|
+
private val getUserUseCase: GetUserUseCase
|
|
41
|
+
) : ViewModel() { ... }
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Koin
|
|
45
|
+
|
|
46
|
+
A pure-Kotlin functional DI framework.
|
|
47
|
+
|
|
48
|
+
**Configuring a Module:**
|
|
49
|
+
|
|
50
|
+
```kotlin
|
|
51
|
+
val appModule = module {
|
|
52
|
+
single<UserRepository> { UserRepositoryImpl(get()) }
|
|
53
|
+
factory { GetUserUseCase(get()) }
|
|
54
|
+
viewModel { UserViewModel(get()) }
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## 3. Best Practices
|
|
59
|
+
|
|
60
|
+
- **Constructor Injection**: Always prefer constructor injection for better testability.
|
|
61
|
+
- **Interface Segregation**: ViewModels and Use Cases should depend on Repository interfaces, not implementations.
|
|
62
|
+
- **Scoped Objects**: Use `@ViewModelScoped` for objects that should live as long as the ViewModel.
|
|
63
|
+
- **Single Source of Truth**: The Repository should be the only component that decides where data comes from.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# CI/CD & Automation for Modern Android
|
|
2
|
+
|
|
3
|
+
Automating the build, test, and release process is essential for maintaining high-quality Android applications in a team environment.
|
|
4
|
+
|
|
5
|
+
## 1. GitHub Actions for Android
|
|
6
|
+
|
|
7
|
+
Use GitHub Actions to run checks on every Pull Request.
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
name: Android CI
|
|
11
|
+
on: [push, pull_request]
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
build:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- name: set up JDK 17
|
|
19
|
+
uses: actions/setup-java@v4
|
|
20
|
+
with:
|
|
21
|
+
java-version: '17'
|
|
22
|
+
distribution: 'temurin'
|
|
23
|
+
cache: gradle
|
|
24
|
+
|
|
25
|
+
- name: Run Lint
|
|
26
|
+
run: ./gradlew lintDebug
|
|
27
|
+
|
|
28
|
+
- name: Run Unit Tests
|
|
29
|
+
run: ./gradlew testDebugUnitTest
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 2. Automated Release with Fastlane
|
|
33
|
+
|
|
34
|
+
Fastlane automates taking screenshots, managing signing certificates, and uploading APKs/Bundles to the Play Store.
|
|
35
|
+
|
|
36
|
+
### Common `Fastfile` Pattern
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
platform :android do
|
|
40
|
+
desc "Deploy a new version to the Google Play Track"
|
|
41
|
+
lane :deploy do
|
|
42
|
+
gradle(task: "bundle", build_type: "Release")
|
|
43
|
+
upload_to_play_store(track: 'internal')
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 3. Best Practices
|
|
49
|
+
|
|
50
|
+
- **Cache Dependencies**: Use caching in your CI YAML to speed up builds.
|
|
51
|
+
- **Fail Fast**: Run lint and unit tests before long-running UI tests.
|
|
52
|
+
- **Secrets Management**: Never commit signing keys; use GitHub Secrets or a vault.
|
|
53
|
+
- **Parallel Testing**: Use Firebase Test Lab for running UI tests across many devices.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Clean Architecture in Modern Android
|
|
2
|
+
|
|
3
|
+
Clean Architecture is a software design philosophy that promotes the separation of concerns, making the system easy to maintain, test, and adapt to changes.
|
|
4
|
+
|
|
5
|
+
## 1. The Core Layers
|
|
6
|
+
|
|
7
|
+
In Clean Architecture, layers are organized like an onion, with the dependency rule stating that **dependencies must only point inwards**.
|
|
8
|
+
|
|
9
|
+
```mermaid
|
|
10
|
+
graph TD
|
|
11
|
+
UI[UI Layer / Controllers] --> UseCase[Use Cases / Domain]
|
|
12
|
+
Data[Data Layer / Presenters] --> UseCase
|
|
13
|
+
UseCase --> Entity[Entities / Business Rules]
|
|
14
|
+
|
|
15
|
+
subgraph "Inner Circles (Stable)"
|
|
16
|
+
Entity
|
|
17
|
+
UseCase
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
subgraph "Outer Circles (Volatile)"
|
|
21
|
+
UI
|
|
22
|
+
Data
|
|
23
|
+
end
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Entities (Inner Circle)
|
|
27
|
+
|
|
28
|
+
- PURE Kotlin/Java objects.
|
|
29
|
+
- Business entities that encapsulate the most general and high-level rules.
|
|
30
|
+
- Least likely to change when something external (UI, Database) changes.
|
|
31
|
+
|
|
32
|
+
### Use Cases (Interactors)
|
|
33
|
+
|
|
34
|
+
- Contains application-specific business logic.
|
|
35
|
+
- Coordinates the flow of data to and from the entities.
|
|
36
|
+
- Defines **what** the user can do (e.g., `GetProductListUseCase`, `AuthenticateUserUseCase`).
|
|
37
|
+
|
|
38
|
+
### Interface Adapters
|
|
39
|
+
|
|
40
|
+
- Converts data from the format most convenient for use cases and entities to the format most convenient for external agencies (UI, DB).
|
|
41
|
+
- ViewModels (UI) and Repositories (Data) live here.
|
|
42
|
+
|
|
43
|
+
## 2. The Dependency Rule
|
|
44
|
+
|
|
45
|
+
The dependency rule is the most important part: **Source code dependencies can only point inwards**.
|
|
46
|
+
|
|
47
|
+
- The `Domain` layer (Entities/Use Cases) must NEVER know about anything in the `Data` or `UI` layers.
|
|
48
|
+
- We achieve this through **Dependency Inversion**: Use interfaces in the Domain layer that are implemented in the Data layer.
|
|
49
|
+
|
|
50
|
+
## 3. Mapping Clean Architecture to MAD
|
|
51
|
+
|
|
52
|
+
Modern Android Development (MAD) simplifies some Clean Architecture concepts for productivity:
|
|
53
|
+
|
|
54
|
+
- **UI Layer**: (Presenters/ViewModels) + Jetpack Compose.
|
|
55
|
+
- **Domain Layer**: (Use Cases). Optional but recommended for complex apps.
|
|
56
|
+
- **Data Layer**: (Repositories + Data Sources like Room/Retrofit).
|
|
57
|
+
|
|
58
|
+
## 4. Key Benefits
|
|
59
|
+
|
|
60
|
+
- **Testability**: You can test the business logic without any UI or DB components.
|
|
61
|
+
- **Independence**: The UI can change from XML to Compose without touching the core logic.
|
|
62
|
+
- **Maintainability**: Clear boundaries prevent the emergence of "God Classes".
|
|
63
|
+
|
|
64
|
+
## 5. Implementation Pattern
|
|
65
|
+
|
|
66
|
+
```kotlin
|
|
67
|
+
// Domain Layer
|
|
68
|
+
class GetUserDetailUseCase(private val userRepository: UserRepository) {
|
|
69
|
+
suspend operator fun invoke(id: String): User = userRepository.getUser(id)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
interface UserRepository {
|
|
73
|
+
suspend fun getUser(id: String): User
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Data Layer
|
|
77
|
+
class UserRepositoryImpl(private val apiService: ApiService) : UserRepository {
|
|
78
|
+
override suspend fun getUser(id: String): User = apiService.fetchUser(id).toDomain()
|
|
79
|
+
}
|
|
80
|
+
```
|