Not Running — apa itu, keadaan awal siklus hidup

Penulis: IT Sectr Diterbitkan: 2026-03-03 Waktu membaca: 11 mnt

Not Running — keadaan awal siklus hidup aplikasi mobile, di mana aplikasi belum dijalankan atau sudah selesai beroperasi. Pelajari bagaimana sistem iOS dan Android mengelola keadaan ini, peristiwa apa yang menyebabkan transisi dari Not Running dan cara menangani dengan benar peluncuran dan penghentian aplikasi di Swift dan Kotlin.

Poin Utama

  • Not Running — aplikasi tidak dimuat ke memori dan tidak menjalankan kode, ini adalah titik masuk dan keluar dalam siklus hidup
  • Peluncuran — transisi dari Not Running terjadi saat mengetuk ikon, melalui deep link atau notifikasi push
  • Penghentian — pengguna menutup aplikasi dengan swipe, sistem membongkarnya saat kekurangan memori atau terjadi crash
  • Start dingin — aplikasi mulai dari nol, semua objek dibuat ulang, keadaan tidak dipulihkan dari cache
  • Start panas — aplikasi berada dalam Suspended dan kembali ke Active tanpa inisialisasi penuh

Not Running — apa keadaan ini

Not Running — adalah keadaan dasar siklus hidup aplikasi mobile, di mana aplikasi tidak dimuat ke dalam RAM perangkat dan tidak mengonsumsi sumber daya sistem. Di iOS dan Android, keadaan ini berarti tidak adanya proses dan thread yang terkait dengan aplikasi. Pengguna melihat ikon aplikasi di desktop, tetapi aplikasi itu sendiri tidak aktif dan tidak ada dalam daftar terbaru.

Ketika pengguna mengetuk ikon, sistem membuat proses baru, memuat kode yang dapat dieksekusi ke memori dan menginisialisasi semua struktur data yang diperlukan. Proses ini disebut start dingin (cold start) dan merupakan yang paling membutuhkan sumber daya dalam hal waktu pemuatan.

Sistem dapat memindahkan aplikasi ke Not Running dari keadaan lain mana pun. Jika aplikasi berada di latar belakang (Background) atau ditangguhkan (Suspended), sistem operasi berhak membongkarnya saat kekurangan RAM untuk tugas yang lebih prioritas — misalnya, untuk aplikasi aktif di latar depan.

Pengembang harus menyadari bahwa aplikasi dapat dihentikan oleh sistem kapan saja saat berada di latar belakang. Ini berarti semua data yang belum disimpan dapat hilang. Oleh karena itu, sangat penting untuk menyimpan keadaan di penyimpanan kunci-nilai (UserDefaults, SharedPreferences) atau di basis data lokal saat transisi dari Active ke Background.

Bagaimana sistem menentukan aplikasi mana yang akan dibongkar

iOS menggunakan prioritas berdasarkan keadaan aplikasi saat ini: Active memiliki prioritas tertinggi, kemudian Inactive, Background, Suspended dan akhirnya Not Running — prioritas minimal. Android menggunakan hierarki proses yang serupa: proses Foreground memiliki prioritas OOM_ADJ = 0, proses Visible = 100, proses Service = 200, proses Background = 300, proses Empty = 400. Semakin tinggi nilainya, semakin besar kemungkinan proses akan dihentikan saat kekurangan memori.

PlatformKeadaanPrioritas pembongkaranDeskripsi
iOSNot RunningTertinggiAplikasi tidak dimuat — sumber daya sistem tidak dikonsumsi
iOSSuspendedTinggiAplikasi di memori, tetapi kode tidak dijalankan — target pertama untuk pembongkaran
iOSBackgroundSedangAplikasi menjalankan tugas latar belakang — dibongkar setelah batas waktu
iOSActiveRendahAplikasi aktif — hanya dibongkar saat kekurangan memori kritis
AndroidEmpty ProcessTertinggiProses tanpa komponen aktif — dihapus pertama
AndroidBackground ProcessTinggiProses latar belakang tanpa Activity yang terlihat
AndroidForeground ServiceRendahLayanan dengan notifikasi — jarang dihentikan
AndroidForeground ProcessMinimalActivity aktif — dihentikan paling akhir

Start dingin dan panas aplikasi

Start dingin (cold start) terjadi ketika aplikasi beralih dari Not Running langsung ke Active. Sistem membuat proses baru, memuat kelas, menginisialisasi bidang statis, membuat thread utama dan menjalankan kerangka UI. Di iOS ini berarti pemanggilan application(_:didFinishLaunchingWithOptions:), di Android — pemanggilan Application.onCreate() dan Activity.onCreate(). Waktu start dingin dapat berkisar dari 200 ms hingga beberapa detik tergantung pada kompleksitas aplikasi.

Start panas (warm start atau hot start) — aplikasi berada dalam keadaan Suspended dan kembali beroperasi tanpa pemuatan ulang penuh. Sistem memulihkan tumpukan UI terakhir dari memori dan pengguna melanjutkan pekerjaan dari tempat yang sama. Start panas secara signifikan lebih cepat daripada start dingin, karena sebagian besar kode sudah dimuat ke memori. Di iOS, start panas tidak memanggil application(_:didFinishLaunchingWithOptions:), hanya applicationWillEnterForeground dan applicationDidBecomeActive.

Perbedaan antara start dingin dan panas sangat penting untuk pengalaman pengguna. Pada start dingin, pengembang harus memastikan bahwa peluncuran terjadi secepat mungkin — inisialisasi malas modul, pemuatan tertunda sumber daya berat, minimalisasi pekerjaan di thread utama saat peluncuran. Google merekomendasikan start dingin tidak lebih dari 500 ms, Apple — tidak lebih dari 400 ms untuk iOS.

kotlin
// Mengukur waktu start dingin di Android
class App : Application() {
    private var startTime: Long = 0L

    override fun onCreate() {
        super.onCreate()
        startTime = System.currentTimeMillis()
    }

    fun getStartupTime(): Long {
        return System.currentTimeMillis() - startTime
    }
}

// Menjalankan Activity dengan inisialisasi malas
class MainActivity : AppCompatActivity() {
    private val viewModel: MainViewModel by lazy {
        ViewModelProvider(this).get(MainViewModel::class.java)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // Hanya minimum yang diperlukan untuk bingkai pertama
        setupNavigation()
    }

    override fun onPostCreate(savedInstanceState: Bundle?) {
        super.onPostCreate(savedInstanceState)
        // Inisialisasi berat setelah rendering
        initializeHeavyModules()
    }
}

Contoh menunjukkan pengukuran waktu start dingin di Android. Application.onCreate() dipanggil saat transisi dari Not Running ke Active. Stempel waktu dicatat saat proses dimulai. Activity menggunakan inisialisasi malas melalui lazy-delegate agar tidak memblokir bingkai pertama. onPostCreate adalah tempat optimal untuk inisialisasi modul berat, karena UI sudah dirender.

Not Running di iOS: Swift dan AppDelegate

Di iOS, Not Running dikelola melalui delegasi UIApplicationDelegate. Metode kunci: application(_:didFinishLaunchingWithOptions:) dipanggil setelah start dingin, applicationWillTerminate(_:) dipanggil sebelum penghentian aplikasi oleh pengguna. Sistem dapat menghentikan aplikasi tanpa memanggil applicationWillTerminate — misalnya, saat penghentian darurat atau pembongkaran memori. iOS tidak menjamin pemanggilan metode ini, oleh karena itu data harus disimpan di applicationDidEnterBackground.

Skenario transisi ke Not Running di iOS

Pengguna dapat menghentikan aplikasi secara manual dengan swipe di App Switcher. Sistem dapat membongkar aplikasi dari memori di latar belakang. Aplikasi dapat berhenti secara darurat (crash). Dalam semua kasus, semua objek yang dibuat saat peluncuran dihancurkan. Keadaan yang tidak disimpan akan hilang secara permanen. Di iOS 13+ untuk menyimpan keadaan disarankan menggunakan NSUserActivity atau mekanisme state restoration melalui UIApplication.stateRestorationIdentifier.

swift
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    // Start dingin: aplikasi beralih dari Not Running
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        // Inisialisasi set layanan minimal
        setupAnalytics()
        configureAppearance()
        return true
    }

    // Aplikasi menghentikan operasi — hanya penutupan manual
    func applicationWillTerminate(
        _ application: UIApplication
    ) {
        saveCriticalData()
    }

    // Menyimpan data sebelum masuk ke latar belakang
    func applicationDidEnterBackground(
        _ application: UIApplication
    ) {
        saveApplicationState()
    }

    private func saveCriticalData() {
        UserDefaults.standard.synchronize()
    }

    private func saveApplicationState() {
        let state = ["lastScreen": "main", "timestamp": Date()]
        try? NSKeyedArchiver.archivedData(
            withRootObject: state,
            requiringSecureCoding: true
        )
    }
}

Kode menunjukkan penanganan Not Running yang benar di iOS. applicationWillTerminate hanya dipanggil saat penghentian manual oleh pengguna. Penyimpanan data kritis diduplikasi di applicationDidEnterBackground, karena metode ini dijamin dipanggil sebelum masuk ke latar belakang. State restoration memungkinkan menyimpan tumpukan UI untuk pemulihan selanjutnya saat start dingin.

Not Running di Android: Kotlin dan proses

Di Android, Not Running berarti proses aplikasi tidak ada. Sistem Linux yang mendasari Android mengelola proses melalui mekanisme Zygote. Saat aplikasi dijalankan, Zygote melakukan fork proses baru, memuat Dalvik/ART dan memanggil Application.onCreate(). Di Android tidak ada analog langsung dari applicationWillTerminate — sistem dapat menghentikan proses kapan saja tanpa peringatan.

Siklus hidup proses Android

Ketika Activity dipanggil untuk pertama kalinya, sistem membuat proses, Application dan Activity melalui rantai onCreate → onStart → onResume. Jika pengguna menekan Back, Activity dihancurkan (onDestroy) dan proses dapat dihentikan oleh sistem. Perbedaan utama dengan iOS: di Android, proses dapat terus ada bahkan tanpa Activity yang aktif — misalnya, jika Foreground Service berjalan atau ada BroadcastReceiver aktif.

kotlin
// Menangani Not Running melalui SavedStateHandle di ViewModel
class MainViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {

    companion object {
        private const val KEY_LAST_SCREEN = "last_screen"
        private const val KEY_USER_DATA = "user_data"
    }

    fun saveCurrentState(screen: String, data: String) {
        savedStateHandle[KEY_LAST_SCREEN] = screen
        savedStateHandle[KEY_USER_DATA] = data
    }

    fun restoreState(): AppState? {
        val screen = savedStateHandle.get<String>(KEY_LAST_SCREEN)
        val data = savedStateHandle.get<String>(KEY_USER_DATA)
        return if (screen != null && data != null) {
            AppState(screen, data)
        } else null
    }
}

// Application — panggilan balik pertama setelah Not Running
class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        initCrashReporter()
        initDependencyInjection()
    }
}

SavedStateHandle — komponen Android Architecture Components yang secara otomatis menyimpan keadaan saat transisi ke Not Running dan memulihkannya saat start dingin. ViewModel yang dibuat melalui ViewModelProvider bertahan dari rotasi layar dan penghancuran Activity. Saat proses dihentikan, data dari SavedStateHandle diserialisasi ke Bundle dan disimpan di saved instance state.

Penyebab transisi ke Not Running

Not Running terjadi karena beberapa alasan. Pengguna menutup aplikasi secara manual. Sistem membongkar aplikasi saat kekurangan memori. Aplikasi berhenti secara darurat dengan pengecualian. Di Android, sistem dapat menghentikan proses saat pembaruan massal aplikasi atau restart perangkat. iOS dapat menghentikan aplikasi saat batas waktu tugas latar belakang (biasanya 30 detik).

PenyebabiOSAndroidKemungkinan pencegahan
Penutupan manual oleh penggunaSwipe di App SwitcherSwipe dari RecentsTidak — tindakan pengguna
Kekurangan memoriPengaktifan memory warningonTrimMemory / LMKSebagian — optimasi memori
Crash aplikasiNSException / sinyalUncaughtException / ANRYa — penanganan kesalahan dan crash-reporting
Batas waktu tugas latar belakang30 detik untuk Background task10 menit untuk JobSchedulerYa — perencanaan tugas yang tepat
Restart OSPemanggilan applicationWillTerminateBroadcast ACTION_SHUTDOWNTidak — peristiwa sistem
Pembaruan aplikasiTidak terjadi (iOS Sandbox)Proses berhenti saat pembaruan APKTidak — pembaruan sistem

Cara mendiagnosis transisi ke Not Running

Untuk iOS, gunakan logging konsol di applicationWillTerminate dan applicationDidFinishLaunching. Tambahkan bendera di UserDefaults setiap kali peluncuran — jika pada start berikutnya bendera tidak ada, aplikasi telah dihentikan secara tidak benar. Di Android gunakan ActivityManager.isBackgroundRestricted() untuk memeriksa apakah aplikasi dapat menjalankan tugas latar belakang. Juga pantau onTrimMemory(TRIM_MEMORY_COMPLETE) — ini adalah sinyal bahwa proses akan dihentikan.

Praktik terbaik bekerja dengan Not Running

Aturan pertama — jangan pernah menganggap bahwa applicationWillTerminate atau onDestroy akan dipanggil. Simpan data yang sangat penting setiap kali transisi dari Active ke Background. Gunakan penyimpanan kunci-nilai untuk pengaturan sederhana dan SQLite/Room untuk data terstruktur.

Aturan kedua — ukur waktu start dingin dan optimalkan. Inisialisasi malas, minimalisasi pekerjaan di thread utama, pemuatan awal sumber daya, penggunaan SplashScreen API — semua ini meningkatkan persepsi waktu peluncuran. Google merekomendasikan start dingin kurang dari 200 ms untuk UX yang sangat baik.

Aturan ketiga — implementasikan State Restoration. Di iOS gunakan UIApplication.stateRestorationIdentifier dan NSUserActivity. Di Android gunakan SavedStateHandle di ViewModel bersama dengan onSaveInstanceState. Ini akan memungkinkan pengguna melanjutkan pekerjaan dari tempat yang sama setelah restart aplikasi.

Aturan keempat — tangani launchOptions dan Intent yang digunakan untuk menjalankan aplikasi setelah Not Running. Deep link, notifikasi push, tautan universal — semuanya diteruskan melalui parameter peluncuran. Pengembang harus mengekstrak data ini dengan benar dan mengarahkan pengguna ke layar yang sesuai.

swift
// Menangani deep link setelah start dingin
func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    // Memeriksa apakah notifikasi tiba
    if let notification = launchOptions?[.remoteNotification] as? [String: Any] {
        handleNotification(notification)
    }
    // Memeriksa deep link
    if let url = launchOptions?[.url] as? URL {
        handleDeepLink(url)
    }
    return true
}

private func handleDeepLink(_ url: URL) {
    guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
          let screenId = components.queryItems?.first(where: { $0.name == "screen" })?.value
    else { return }
    openScreen(screenId)
}

Kode menunjukkan penanganan parameter peluncuran saat start dingin di iOS. launchOptions berisi data yang digunakan sistem untuk menjalankan aplikasi. Notifikasi, deep link dan tautan universal diteruskan melalui kamus ini. Pengembang harus menangani semua skenario peluncuran yang mungkin untuk memastikan pengalaman pengguna yang mulus.

Pertanyaan yang Sering Diajukan

Apa yang terjadi pada data saat transisi ke Not Running?

Data yang disimpan di penyimpanan permanen (UserDefaults, Core Data, SharedPreferences, Room) tetap terjaga. Data di RAM — variabel, cache, keadaan ViewModel tanpa SavedStateHandle — hilang secara permanen. Oleh karena itu, sangat penting untuk menyimpan keadaan aplikasi setiap kali transisi ke latar belakang.

Bagaimana membedakan start dingin dari start panas di iOS?

Saat start dingin, application(_:didFinishLaunchingWithOptions:) dipanggil. Saat start panas (kembali dari Suspended), metode ini tidak dipanggil — hanya applicationWillEnterForeground dan applicationDidBecomeActive yang aktif. Jika Anda perlu melakukan tindakan hanya saat start dingin, setel bendera di didFinishLaunchingWithOptions.

Bisakah aplikasi Android berada dalam Not Running dengan Service aktif?

Ya. Foreground Service dengan notifikasi permanen mencegah penghentian proses oleh sistem, bahkan jika semua Activity dihancurkan. Background Service (startService tanpa foreground) dapat dihentikan oleh sistem kapan saja. Service yang berjalan berarti proses ada dan ini bukan lagi Not Running.

Bagaimana cara meniru Not Running di simulator?

Di simulator iOS, hentikan aplikasi melalui App Switcher (Cmd+Shift+H dua kali, swipe ke atas). Di emulator Android, gunakan adb shell am force-stop com.example.app atau tombol Stop di Logcat. Kemudian jalankan aplikasi lagi — ini akan menjadi start dingin bersih dari Not Running.

Apa itu kill-switch dalam konteks Not Running?

Kill-switch — perintah server untuk penghentian darurat aplikasi. Digunakan di aplikasi perbankan dan perusahaan untuk memblokir akses jarak jauh. Jika aplikasi menerima perintah kill, pada start dingin berikutnya akan memblokir UI dan meminta otorisasi ulang. Di iOS, kill-switch diimplementasikan melalui remote notifications dengan bendera pemblokiran.

Ringkasan

  • Not Running — keadaan awal dan akhir siklus hidup, aplikasi tidak dimuat ke memori dan tidak menjalankan kode
  • Start dingin — pemuatan ulang penuh aplikasi dari Not Running, memerlukan inisialisasi semua komponen dari nol
  • Start panas — kembali dari Suspended, tidak memanggil didFinishLaunchingWithOptions atau Application.onCreate
  • Penyimpanan data — sangat penting saat transisi ke Background, karena Not Running dapat terjadi kapan saja
  • iOS — applicationWillTerminate tidak dijamin, keadaan disimpan melalui UserDefaults atau state restoration
  • Android — proses dapat dihentikan kapan saja, SavedStateHandle di ViewModel menyimpan keadaan secara otomatis
  • Optimasi peluncuran — inisialisasi malas, pekerjaan minimal di main thread, SplashScreen API untuk bingkai pertama cepat

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga