onCreate — τι είναι, αρχικοποίηση Activity στο Android

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-03-03 Χρόνος ανάγνωσης: 10 λεπ

onCreate — είναι η πρώτη και μοναδική υποχρεωτική μέθοδος του κύκλου ζωής Activity και Fragment στο Android. Το σύστημα την καλεί μία φορά κατά τη δημιουργία του component, μεταβιβάζοντας την παράμετρο Bundle με την προηγουμένως αποθηκευμένη κατάσταση. Μέσα στο onCreate ο προγραμματιστής αρχικοποιεί τη διεπαφή χρήστη, συνδέει τα στοιχεία View, ρυθμίζει τους χειριστές συμβάντων και επαναφέρει δεδομένα από το savedInstanceState. Χωρίς σωστή υλοποίηση του onCreate, καμία εφαρμογή Android δεν μπορεί να εκκινηθεί — είναι το σημείο εισόδου για κάθε οθόνη. Διαβάστε περισσότερα για τον γενικό κύκλο ζωής Activity στο άρθρο Activity Lifecycle.

Κύρια σημεία

  • onCreate — πρώτη και μοναδική υποχρεωτική μέθοδος του κύκλου ζωής; καλείται μία φορά κατά τη δημιουργία Activity ή Fragment
  • Παράμετρος Bundle — το savedInstanceState περιέχει δεδομένα αποθηκευμένα στο onSaveInstanceState ή null αν το Activity δημιουργείται για πρώτη φορά
  • setContentView — υποχρεωτική κλήση μέσα στο onCreate για Activity; συνδέει τη διάταξη XML με τον κώδικα
  • Αρχικοποίηση UI — findViewById, ρύθμιση προσαρμογέων RecyclerView, ορισμός ακροατών κλικ — τυπικές εργασίες του onCreate
  • Fragment.onCreate — διαφέρει από το Activity: εδώ δεν καλείται setContentView, η διάταξη μεταβιβάζεται μέσω onCreateView
  • Χρονικός περιορισμός — το onCreate πρέπει να ολοκληρωθεί σε 5 δευτερόλεπτα (όριο ANR), οι μακροχρόνιες λειτουργίες μεταφέρονται σε νήμα παρασκηνίου
  • ViewModel και onCreate — η αρχικοποίηση ViewModel στο onCreate επιτρέπει στα δεδομένα να επιβιώσουν από την περιστροφή οθόνης χωρίς απώλεια

Τι είναι το onCreate στο Android

onCreate — μια μέθοδος callback που καλεί το Android κατά τη δημιουργία μιας νέας παρουσίας Activity ή Fragment. Αυτό είναι το πρώτο σημείο εισόδου στον κώδικα της οθόνης χρήστη: πριν από την κλήση του onCreate, δεν εκτελείται κανένας κώδικας χρήστη. Το σύστημα μεταβιβάζει στη μέθοδο την παράμετρο Bundle, η οποία είτε περιέχει προηγουμένως αποθηκευμένα δεδομένα (κατά την αναδημιουργία) είτε είναι null (κατά την πρώτη εκκίνηση).

Η μέθοδος onCreate ορίζεται στην κλάση android.app.Activity και στην κλάση androidx.fragment.app.Fragment. Και οι δύο παραλλαγές εκτελούν παρόμοιες εργασίες: αρχικοποίηση του component, ρύθμιση UI και επαναφορά κατάστασης. Ωστόσο, η συγκεκριμένη υλοποίηση διαφέρει — το Activity χρησιμοποιεί setContentView για τη φόρτωση της διάταξης, ενώ το Fragment επιστρέφει View μέσω του onCreateView. Ο προγραμματιστής υποχρεούται να παρακάμψει τουλάχιστον το onCreate στο Activity — χωρίς αυτό, το Android δεν μπορεί να εμφανίσει την οθόνη.

Το onCreate καλείται αυστηρά μία φορά κατά τη διάρκεια ολόκληρου του κύκλου ζωής της παρουσίας Activity. Ακόμη και κατά την περιστροφή οθόνης, η νέα παρουσία Activity λαμβάνει μια νέα κλήση onCreate με το Bundle από την προηγούμενη παρουσία. Αυτή η ιδιότητα καθιστά το onCreate ιδανικό μέρος για εφάπαξ αρχικοποίηση: φόρτωση δεδομένων, δημιουργία προσαρμογέων, ρύθμιση component DI μέσω Dagger ή Hilt.

onCreate στο Activity

Στο Activity, η μέθοδος onCreate εκτελεί τέσσερις βασικές εργασίες: φόρτωση διάταξης layout, αρχικοποίηση στοιχείων View, επαναφορά κατάστασης από Bundle και ρύθμιση πρωταρχικών χειριστών συμβάντων. Ο υποχρεωτικός ελάχιστος κώδικας στο onCreate — κλήση super.onCreate(savedInstanceState) και setContentView(R.layout.activity_main).

kotlin
class MainActivity : AppCompatActivity() {
    private var binding: ActivityMainBinding? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // ViewBinding — σύγχρονη αντικατάσταση του findViewById
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding?.root)

        // Αρχικοποίηση με χρήση binding
        binding?.apply {
            welcomeText.text = getString(R.string.welcome)
            startButton.setOnClickListener { startGame() }
        }

        // Επαναφορά κατάστασης
        if (savedInstanceState != null) {
            score = savedInstanceState.getInt("score", 0)
            binding?.scoreText?.text = score.toString()
        }
    }
}

Σύγχρονη πρακτική — χρήση ViewBinding αντί για findViewById. Το ViewBinding δημιουργεί την κλάση ActivityMainBinding στο στάδιο μεταγλώττισης, εξαλείφοντας σφάλματα με λανθασμένα ID και μειώνοντας τον όγκο του κώδικα πρότυπου. Η Google συνιστά το ViewBinding ως τον τυπικό τρόπο πρόσβασης στο View σε Activity και Fragment από το Android Studio 3.6.

Η σειρά ενεργειών στο onCreate πρέπει να είναι αυστηρή: πρώτα super, μετά setContentView, έπειτα όλα τα υπόλοιπα. Η κλήση findViewById πριν από το setContentView επιστρέφει null — η διάταξη δεν έχει ακόμη φορτωθεί και τα στοιχεία View δεν υπάρχουν στην ιεραρχία. Αυτό είναι ένα από τα πιο συνηθισμένα λάθη αρχάριων προγραμματιστών Android.

onCreate στο Fragment

Το onCreate στο Fragment διαφέρει από το Activity: εδώ δεν καλείται setContentView, εκτελείται μόνο αρχικοποίηση δεδομένων που δεν σχετίζονται με UI. Το Fragment διαχωρίζει τη δημιουργία του component και τη δημιουργία View σε δύο ξεχωριστές μεθόδους: onCreate (καλείται μία φορά) και onCreateView (καλείται κάθε φορά κατά τη δημιουργία ή αναδημιουργία του View).

kotlin
class UserListFragment : Fragment() {
    private lateinit var viewModel: UserViewModel
    private var binding: FragmentUserListBinding? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Αρχικοποίηση ViewModel — θα επιβιώσει από την αναδημιουργία View
        viewModel = ViewModelProvider(this)[UserViewModel::class.java]

        // Ορίσματα από FragmentManager
        arguments?.let {
            viewModel.loadUser(it.getString("user_id") ?: "")
        }

        // Αποθήκευση κατά την περιστροφή
        retainInstance = true
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentUserListBinding.inflate(inflater, container, false)
        return binding!!.root
    }
}

Η βασική διαφορά μεταξύ onCreate Activity και Fragment: το onCreate στο Fragment δεν πρέπει να περιέχει κώδικα που σχετίζεται με View, επειδή το View μπορεί να καταστραφεί και να δημιουργηθεί ξανά (για παράδειγμα, κατά την εναλλαγή καρτελών ViewPager), ενώ το onCreate καλείται μόνο μία φορά. Φόρτωση δεδομένων, ρύθμιση ViewModel και αρχικοποίηση προσαρμογέων — εργασίες του onCreate, ενώ η σύνδεση View — εργασία του onViewCreated.

savedInstanceState και επαναφορά κατάστασης

Η παράμετρος savedInstanceState στο onCreate — είναι ο μηχανισμός αποθήκευσης και επαναφοράς της προσωρινής κατάστασης Activity ή Fragment. Όταν το σύστημα καταστρέφει το Activity (περιστροφή οθόνης, έλλειψη μνήμης), καλεί onSaveInstanceState(), στο οποίο ο προγραμματιστής τοποθετεί ένα ζεύγος κλειδιού-τιμής στο Bundle. Κατά τη δημιουργία νέας παρουσίας, αυτό το Bundle επιστρέφεται στο onCreate.

Το Bundle υποστηρίζει τους ακόλουθους τύπους δεδομένων: String, Integer, Boolean, Long, Float, Double, τους πίνακές τους, καθώς και αντικείμενα Parcelable και Serializable. Για σύνθετα αντικείμενα χρησιμοποιείται Parcelable — ένας πιο αποδοτικός μηχανισμός σειριοποίησης, ειδικός για Android. Το μέγεθος του Bundle περιορίζεται σε περίπου 500 KB — η υπέρβαση του ορίου προκαλεί εξαίρεση TransactionTooLargeException.

kotlin
companion object {
    private const val KEY_USER_NAME = "user_name"
    private const val KEY_SCORE = "score"
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_game)

    if (savedInstanceState != null) {
        userName = savedInstanceState.getString(KEY_USER_NAME) ?: ""
        currentScore = savedInstanceState.getInt(KEY_SCORE)
    }
}

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putString(KEY_USER_NAME, userName)
    outState.putInt(KEY_SCORE, currentScore)
}

Είναι σημαντικό να κατανοήσετε: το onSaveInstanceState δεν καλείται όταν ο χρήστης κλείνει ρητά το Activity μέσω finish() ή πατώντας το κουμπί «Πίσω». Το σύστημα θεωρεί ότι σε αυτήν την περίπτωση ο χρήστης συνειδητά τερματίζει την εργασία και η αποθήκευση κατάστασης δεν απαιτείται. Επομένως, δεν πρέπει να βασίζεστε αποκλειστικά στο savedInstanceState για μακροπρόθεσμη αποθήκευση δεδομένων — χρησιμοποιήστε Room, DataStore ή SharedPreferences.

Χρονισμός και περιορισμοί του onCreate

Το onCreate εκτελείται στο κύριο (UI) νήμα και το σύστημα περιμένει την ολοκλήρωσή του πριν εμφανίσει το Activity στην οθόνη. Αν το onCreate διαρκέσει περισσότερο από 5 δευτερόλεπτα, το σύστημα εμφανίζει ένα παράθυρο διαλόγου ANR (Application Not Responding) και προτείνει στον χρήστη να κλείσει την εφαρμογή. Οι μακροχρόνιες λειτουργίες, όπως η φόρτωση δεδομένων από το δίκτυο ή η ανάγνωση από τη βάση δεδομένων, πρέπει να μεταφέρονται σε νήμα παρασκηνίου.

Σύμφωνα με τις συστάσεις Google Android Performance (2025), το onCreate πρέπει να ολοκληρώνεται σε λιγότερο από 1 δευτερόλεπτο σε συσκευές μεσαίου τμήματος. Για αυτό, πρέπει: να χρησιμοποιείτε τεμπέλικη αρχικοποίηση (lazy delegate σε Kotlin), να αναβάλλετε τη φόρτωση βαρέων δεδομένων στο onResume ή μέσω coroutine, να εφαρμόζετε ViewStub για σπάνια χρησιμοποιούμενα component UI, να προφιλάρετε τον χρόνο εκκίνησης μέσω Android Vitals.

kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Τεμπέλικη αρχικοποίηση — το αντικείμενο δημιουργείται μόνο στην πρώτη πρόσβαση
    val heavyData by lazy {
        HeavyDataLoader.load()
    }

    // Φόρτωση δεδομένων σε νήμα παρασκηνίου μέσω lifecycleScope
    lifecycleScope.launch(Dispatchers.IO) {
        val users = userDao.getAllUsers()
        withContext(Dispatchers.Main) {
            adapter.submitList(users)
        }
    }
}

Εργαλεία προφίλ: το Android Studio Profiler (καρτέλα CPU) δείχνει τον ακριβή χρόνο εκτέλεσης κάθε μεθόδου. Στο Android Vitals (κονσόλα Google Play) μπορείτε να παρακολουθείτε τη μετρική «Χρόνος ψυχρής εκκίνησης» — αν το onCreate του Activity σας υπερβαίνει τα 500 ms, η κονσόλα το επισημαίνει ως πρόβλημα απόδοσης. Εμείς στην IT Sectr χρησιμοποιούμε δοκιμές Macrobenchmark για αυτόματο έλεγχο του χρόνου εκκίνησης κάθε Activity στο pipeline CI.

ViewModel και onCreate

ViewModel — ο καλύτερος τρόπος αρχικοποίησης δεδομένων στο onCreate που πρέπει να επιβιώσουν από την περιστροφή οθόνης. Το ViewModel δημιουργείται στο onCreate μέσω ViewModelProvider και αποθηκεύεται αυτόματα κατά την αλλαγή διαμόρφωσης. Όταν το Activity αναδημιουργείται μετά από περιστροφή, το ViewModel παραμένει στη μνήμη και το onCreate λαμβάνει το ίδιο ViewModel χωρίς απώλεια δεδομένων.

kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_profile)

    // Το ViewModel δημιουργείται μία φορά και επιβιώνει από αλλαγές διαμόρφωσης
    val viewModel: ProfileViewModel =
        ViewModelProvider(this)[ProfileViewModel::class.java]

    // Παρατήρηση LiveData — το UI ενημερώνεται αυτόματα όταν αλλάζουν τα δεδομένα
    viewModel.user.observe(this) { user ->
        binding?.userName?.text = user.name
        binding?.userEmail?.text = user.email
    }

    // Φόρτωση δεδομένων αν το ViewModel μόλις δημιουργήθηκε
    if (savedInstanceState == null) {
        viewModel.loadProfile(userId)
    }
}

Ο συνδυασμός ViewModel + LiveData/StateFlow λύνει το πρόβλημα της περιστροφής οθόνης χωρίς χειροκίνητη αποθήκευση στο Bundle. Το ViewModel αποθηκεύει δεδομένα στη μνήμη, το LiveData αυτόματα επανεγγράφει το Activity κατά την αναδημιουργία και το StateFlow (από Kotlin Coroutines) προσθέτει αντιδραστικότητα με υποστήριξη coroutine. Αυτή είναι η τυπική αρχιτεκτονική που συνιστά η Google στον οδηγό Guide to App Architecture.

Συχνά λάθη κατά την εργασία με το onCreate

Ακόμη και έμπειροι προγραμματιστές κάνουν τυπικά λάθη στο onCreate. Ας εξετάσουμε πέντε από τα πιο συνηθισμένα προβλήματα και τρόπους αποφυγής τους.

Εργασία με View πριν από setContentView

Το πιο συνηθισμένο λάθος — προσπάθεια εύρεσης View μέσω findViewById πριν από την κλήση setContentView. Όλα τα στοιχεία View δημιουργούνται τη στιγμή της διόγκωσης της διάταξης, επομένως οποιαδήποτε αναφορά σε findViewById πριν από setContentView επιστρέφει null και προκαλεί NullPointerException κατά την προσπάθεια χρήσης View. Λύση: αυστηρή σειρά — πρώτα super, μετά setContentView, έπειτα findViewById ή ViewBinding.

Μπλοκάρισμα νήματος UI με μακροχρόνιες λειτουργίες

Η φόρτωση δεδομένων από το δίκτυο, η ανάγνωση από τη βάση δεδομένων ή η επεξεργασία μεγάλων πινάκων απευθείας στο onCreate μπλοκάρει την απόδοση του πρώτου καρέ. Ο χρήστης βλέπει μια μαύρη οθόνη μέχρι να ολοκληρωθεί το onCreate, γεγονός που υποβαθμίζει την αντίληψη της ταχύτητας της εφαρμογής. Λύση: χρησιμοποιήστε lifecycleScope.launch για ασύγχρονες λειτουργίες, εμφανίστε έναν σκελετό (placeholder UI) μέχρι να ολοκληρωθεί η φόρτωση.

Αγνόηση του savedInstanceState

Αν κατά την περιστροφή οθόνης δεν επαναφέρεται η κατάσταση από το Bundle, ο χρήστης χάνει όλη τη μη αποθηκευμένη είσοδο: κείμενο σε πεδία φόρμας, θέση κύλισης, επιλεγμένα στοιχεία. Λύση: ελέγχετε πάντα savedInstanceState != null στο onCreate για επαναφορά δεδομένων, ακόμη κι αν η απώλεια κατάστασης φαίνεται απίθανη.

Διαρροή μνήμης μέσω ανώνυμων κλάσεων

Οι ανώνυμες κλάσεις και τα lambda στο onCreate μπορούν σιωπηρά να διατηρήσουν αναφορά στο Activity μετά την καταστροφή του. Για παράδειγμα, ένα Handler που δημιουργήθηκε στο onCreate συνεχίζει να εκτελεί καθυστερημένες εργασίες ακόμη και μετά την καταστροφή του Activity. Λύση: χρησιμοποιήστε LifecycleObserver, ViewModel και lifecycleScope, που ακυρώνουν αυτόματα εργασίες κατά την καταστροφή.

Υπερβολική αρχικοποίηση στο onCreate Fragment

Η αρχικοποίηση View στο onCreate Fragment — λογικό λάθος, επειδή το View μπορεί να αναδημιουργηθεί χωρίς κλήση του onCreate. Αν οριστεί ένας ακροατής στο onCreate και το View συνδεθεί στο onCreateView, κατά την αναδημιουργία ο ακροατής παραμένει στο παλιό View. Λύση: όλη η εργασία με View εκτελείται στο onViewCreated, και το onCreate αφήνεται μόνο για αρχικοποίηση του επιπέδου δεδομένων.

Συχνές ερωτήσεις

Είναι υποχρεωτική η παράκαμψη του onCreate στο Activity;

Ναι, η παράκαμψη του onCreate είναι υποχρεωτική για κάθε Activity που εμφανίζει διεπαφή χρήστη. Χωρίς αυτήν, δεν μπορεί να κληθεί setContentView και να φορτωθεί η διάταξη XML. Αν το Activity δεν έχει UI (για παράδειγμα, ένα διαφανές Activity-υποκατάστατο), το onCreate παρακάμπτεται ωστόσο, αλλά χωρίς κλήση setContentView.

Μπορεί το onCreate να κληθεί ξανά χωρίς καταστροφή του Activity;

Όχι, το onCreate δεν μπορεί να κληθεί ξανά για την ίδια παρουσία Activity. Αν το Activity καταστραφεί και δημιουργηθεί ξανά (περιστροφή οθόνης, έλλειψη μνήμης), αυτή είναι ήδη μια νέα παρουσία με νέα κλήση onCreate. Εξαίρεση — η μέθοδος recreate(), που αναγκάζει την καταστροφή και αναδημιουργία του Activity, αλλά αυτό είναι αναδημιουργία νέας παρουσίας.

Τι συμβαίνει αν δεν κληθεί το super.onCreate;

Αν δεν κληθεί το super.onCreate(savedInstanceState), το Android Runtime θα πετάξει εξαίρεση SuperNotCalledException και η εφαρμογή θα καταρρεύσει. Το σύστημα απαιτεί αυστηρά κάθε παρακαμφθείσα μέθοδος κύκλου ζωής να καλεί την super έκδοσή της — αυτό εγγυάται τη σωστή λειτουργία της εσωτερικής μηχανής καταστάσεων.

Τι διαφορά έχει το onCreate στο Activity από το onCreate στο Fragment;

Η βασική διαφορά: το onCreate στο Activity φορτώνει UI μέσω setContentView, ενώ το onCreate στο Fragment μόνο αρχικοποιεί δεδομένα. Το Fragment δημιουργεί View στην ξεχωριστή μέθοδο onCreateView, που μπορεί να κληθεί πολλές φορές (για παράδειγμα, κατά την εναλλαγή καρτελών), ενώ το onCreate του Fragment καλείται μία φορά κατά τη διάρκεια ζωής της παρουσίας Fragment.

Πώς να μεταφέρετε δεδομένα από το onCreate σε άλλες μεθόδους;

Τα δεδομένα που αρχικοποιούνται στο onCreate αποθηκεύονται στα πεδία της κλάσης Activity ή Fragment. Για παράδειγμα, το private lateinit var binding: ActivityMainBinding δηλώνεται σε επίπεδο κλάσης, αρχικοποιείται στο onCreate και είναι προσβάσιμο σε όλες τις επόμενες μεθόδους. Για δεδομένα που επιβιώνουν από περιστροφή οθόνης, χρησιμοποιήστε ViewModel με LiveData ή StateFlow.

Περίληψη

  • onCreate — υποχρεωτική μέθοδος κύκλου ζωής, καλείται μία φορά κατά τη δημιουργία Activity ή Fragment
  • setContentView — υποχρεωτική κλήση για Activity, φορτώνει τη διάταξη XML; για Fragment η διάταξη φορτώνεται μέσω onCreateView
  • savedInstanceState — Bundle με αποθηκευμένη κατάσταση κατά την αναδημιουργία; null στην πρώτη εκκίνηση
  • Χρονικός περιορισμός — το onCreate πρέπει να εκτελείται σε λιγότερο από 1 δευτερόλεπτο, οι μακροχρόνιες λειτουργίες μεταφέρονται σε coroutine
  • ViewModel — η αρχικοποίηση ViewModel στο onCreate λύνει το πρόβλημα απώλειας δεδομένων κατά την περιστροφή οθόνης
  • Fragment vs Activity — το onCreate Fragment δεν περιέχει κώδικα UI, το onCreate Activity φορτώνει διάταξη μέσω setContentView
  • Πέντε τυπικά λάθη — εργασία με View πριν από setContentView, μπλοκάρισμα UI, αγνόηση Bundle, διαρροή μνήμης, κώδικας UI σε Fragment.onCreate

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης