skills/mobile/android-kotlin/SKILL.md
Kotlin for Android: ViewModel, LiveData/StateFlow, coroutines viewModelScope, Gradle KTS, KTX
npx skillsauth add alphaonedev/openclaw-graph android-kotlinInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill provides guidance on using Kotlin for Android development, focusing on key components like ViewModel for state management, LiveData or StateFlow for reactive data, coroutines with viewModelScope for asynchronous operations, Gradle KTS for build configuration, and KTX for Android extensions. It helps in building robust, maintainable Android apps.
Use this skill when developing Android apps in Kotlin that require: managing UI state with ViewModel; handling asynchronous tasks like network calls using coroutines; observing data changes with LiveData or StateFlow; configuring projects via Gradle KTS; or simplifying code with KTX extensions. Apply it in scenarios involving activities, fragments, or services where lifecycle-aware components are needed.
androidx.lifecycle.ViewModel class.viewModelScope.launch {} for scoped coroutines that cancel on ViewModel destruction.build.gradle.kts.ContextCompat from androidx.core.To implement MVVM architecture, create a ViewModel to hold data and business logic, then observe it in activities or fragments. For asynchronous operations, always launch coroutines within viewModelScope to avoid leaks. Use LiveData for simple observations or StateFlow for more advanced flows. When configuring Gradle, switch to KTS by renaming build.gradle to build.gradle.kts and updating syntax. Integrate KTX by adding dependencies in build.gradle.kts, e.g., implementation "androidx.core:core-ktx:1.7.0".
./gradlew build --stacktrace for debugging; use ./gradlew assembleDebug to build debug APK.ViewModel class; example: class MyViewModel : ViewModel() { val data = MutableLiveData<String>() }.kotlinx.coroutines; use viewModelScope.launch { delay(1000); data.value = "Updated" } for delayed updates.val liveData = MutableLiveData<String>(); or val stateFlow = MutableStateFlow("").requireContext().toast("Message") from androidx.fragment.app.Fragment KTX for showing toasts.dependencies { implementation("com.android.tools.build:gradle:7.0.0") }; set API keys via environment variables like buildConfigField "String", "API_KEY", "\"$SYSTEM_ENV_API_KEY\"".To integrate ViewModel, add androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0 to build.gradle.kts, then inject it using ViewModelProvider(this).get(MyViewModel::class.java). For coroutines, include org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0 and ensure viewModelScope is used in ViewModel subclasses. When using StateFlow, combine with lifecycleScope.launchWhenStarted { viewModel.stateFlow.collect { updateUI(it) } } in fragments. For auth, handle API keys by setting them as environment variables (e.g., $ANDROID_API_KEY) and accessing via BuildConfig.API_KEY. Ensure AndroidX compatibility by migrating from support libraries.
Handle exceptions in coroutines with try-catch blocks: viewModelScope.launch { try { val result = apiCall() } catch (e: Exception) { data.value = "Error: ${e.message}" } }. For LiveData, use observe with lifecycle owner and handle null values: viewModel.data.observe(this) { if (it != null) updateUI(it) else showError() }. In Gradle, debug builds with --stacktrace or --debug flags, e.g., ./gradlew build --stacktrace. Monitor StateFlow errors by wrapping emissions in try-catch during collection. Always check for null in KTX extensions, like if (context != null) context.startActivity(intent).
class UserViewModel : ViewModel() { val userData = MutableLiveData<String>() fun loadData() { userData.value = "Loaded" } }. In an activity: val viewModel: UserViewModel by viewModels(); viewModel.userData.observe(this) { textView.text = it }. Call viewModel.loadData() on button click.class DataViewModel : ViewModel() { fun fetchData() = viewModelScope.launch { val result = withContext(Dispatchers.IO) { apiService.getData() } data.value = result } }. Observe in fragment: viewModel.data.observe(viewLifecycleOwner) { if (it.isSuccess) showData(it) else handleError() }.tools
Root web development: project structure, tooling selection, deployment decisions
development
WebAssembly: Rust/Go/C to WASM, wasm-bindgen, Emscripten, WASM Component Model
development
Vue 3: Composition API script setup, Pinia, Vue Router 4, SFCs, Vite, Nuxt 3
tools
Tailwind CSS 4: utility classes, config, JIT, arbitrary values, darkMode, plugins, shadcn/ui