{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreigfv3jwggww5qofuiwsjqgzof277i4ipltenqikegwfp3j6x2adma",
    "uri": "at://did:plc:25rdn5elo5izoxrmtis34zuk/app.bsky.feed.post/3mowvpy5odyy2"
  },
  "coverImage": {
    "$type": "blob",
    "ref": {
      "$link": "bafkreicv3wdjmmf7q6y7xq4dfjt3yxjlyzqjmo4neuc33isx6ayckhxlmm"
    },
    "mimeType": "image/webp",
    "size": 60384
  },
  "path": "/manoj_saichallagulla_798/viewmodel-vs-coroutine-scope-oln",
  "publishedAt": "2026-06-23T07:05:01.000Z",
  "site": "https://dev.to",
  "tags": [
    "android",
    "beginners",
    "mobile",
    "tutorial"
  ],
  "textContent": "##  1. Coroutine\n\nA coroutine is the actual background task.\n\nExample:\n\n\n\n    launch {\n        api.getProfile()\n    }\n\n\nHere, the work is:\n\n##  api.getProfile()\n\nSo coroutine means:\n\nA lightweight task that can run without blocking the main thread.\n\n##  2. CoroutineScope\n\nA CoroutineScope is like a container/manager for coroutines.\n\nIt decides:\n\n\n\n    Where coroutine runs\n    How long coroutine lives\n    When coroutine should be cancelled\n\n\nExample:\n\n\n\n    val scope = CoroutineScope(Dispatchers.IO)\n\n    scope.launch {\n        // coroutine work\n    }\n\n\nHere:\n\n\n\n    scope = manager\n    launch block = coroutine\n\n\n\n##  3. viewModelScope\n\nviewModelScope is a special CoroutineScope given by Android to every ViewModel.\n\nExample:\n\n\n\n    class ProfileViewModel : ViewModel() {\n\n        fun loadProfile() {\n            viewModelScope.launch {\n                repository.getProfile()\n            }\n        }\n    }\n\n\nMeaning:\n\nRun this coroutine inside the ViewModel’s scope.\n\n\n\n    4. Relationship\n\n\nVery important:\n\n\n\n    CoroutineScope is the general concept.\n\n    viewModelScope is one specific CoroutineScope.\n\n    Coroutine is the actual task running inside the scope.\n\n\nLike this:\n\n\n\n    ViewModel\n       owns\n    viewModelScope\n       manages\n    coroutines\n\n\nVisual:\n\n`ProfileViewModel\n│\n└── viewModelScope\n│\n├── coroutine 1 → API call\n├── coroutine 2 → DB operation\n└── coroutine 3 → file operation`\n\n##  5. Why use viewModelScope?\n\nBecause it automatically cancels coroutines when ViewModel is cleared.\n\n\n\n    viewModelScope.launch {\n        delay(10000)\n        println(\"Done\")\n    }\n\n\nIf user leaves the screen before 10 seconds:\n\n\n\n    Screen closed\n    ↓\n    ViewModel cleared\n    ↓\n    viewModelScope cancelled\n    ↓\n    Coroutine cancelled\n\n\nSo \"Done\" will not print.\n\n##  6. Without viewModelScope\n\n\n    val scope = CoroutineScope(Dispatchers.IO)\n\n    scope.launch {\n        delay(10000)\n        println(\"Done\")\n    }\n\n\nHere you created the scope manually.\n\nSo you must cancel it manually:\n\n\n\n    scope.cancel()\n\n\n\nOtherwise it may continue even after the screen is gone.\n\n##  7. Final Note\n\n\n    Write this in your notes:\n\n    Coroutine = actual background task.\n\n    CoroutineScope = manager/container that controls coroutines.\n\n    viewModelScope = Android-provided CoroutineScope attached to ViewModel.\n\n    When ViewModel is cleared, viewModelScope is automatically cancelled.\n\n    So all coroutines launched inside viewModelScope are also cancelled.\n\n\n\nBest simple line:\n\nviewModelScope.launch { } means:\n\n\n\n    Run this coroutine as long as the ViewModel is alive.\n",
  "title": "ViewModel VS Coroutine Scope"
}