onCreate چیست، مقداردهی اولیه Activity در Android

نویسنده: IT Sectr منتشر شده: 2026-03-03 زمان مطالعه: 10 دقیقه

onCreate — اولین و تنها متد اجباری چرخه حیات Activity و Fragment در Android است. سیستم یک بار هنگام ایجاد کامپوننت آن را فراخوانی می‌کند و پارامتر 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 باید در ۵ ثانیه به پایان برسد (آستانه ANR)، عملیات طولانی به رشته پس‌زمینه منتقل می‌شوند
  • ViewModel و onCreate — مقداردهی اولیه ViewModel در onCreate به داده‌ها اجازه می‌دهد بدون از دست دادن چرخش صفحه را تحمل کنند

onCreate در Android چیست

onCreate — متد فراخوان (callback) است که Android هنگام ایجاد یک نمونه جدید از Activity یا Fragment آن را فراخوانی می‌کند. این اولین نقطه ورود به کد صفحه کاربر است: قبل از فراخوانی onCreate هیچ کد کاربری اجرا نمی‌شود. سیستم پارامتر Bundle را به متد ارسال می‌کند که یا حاوی داده‌های ذخیره‌شده قبلی است (در هنگام بازسازی) یا برابر null است (در اولین راه‌اندازی).

متد onCreate در کلاس android.app.Activity و در کلاس androidx.fragment.app.Fragment تعریف شده است. هر دو variant وظایف مشابهی را انجام می‌دهند: مقداردهی اولیه کامپوننت، پیکربندی UI و بازیابی وضعیت. با این حال پیاده‌سازی خاص متفاوت است — Activity از setContentView برای بارگذاری چیدمان استفاده می‌کند، در حالی که Fragment از طریق onCreateView View را برمی‌گرداند. توسعه‌دهنده موظف است حداقل onCreate را در Activity بازنویسی کند — بدون این Android نمی‌تواند صفحه را نمایش دهد.

onCreate دقیقاً یک بار در طول چرخه حیات کامل نمونه Activity فراخوانی می‌شود. حتی هنگام چرخش صفحه، نمونه جدید Activity یک فراخوانی جدید onCreate با Bundle از نمونه قبلی دریافت می‌کند. این ویژگی onCreate را به مکان ایده‌آلی برای مقداردهی اولیه یکباره تبدیل می‌کند: بارگذاری داده‌ها، ایجاد آداپتورها، پیکربندی کامپوننت‌های 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 از Android Studio 3.6 به بعد ViewBinding را به عنوان روش استاندارد دسترسی به View در Activity و Fragment توصیه می‌کند.

ترتیب اقدامات در onCreate باید دقیق باشد: ابتدا super، سپس setContentView، سپس بقیه موارد. فراخوانی findViewById قبل از setContentView null برمی‌گرداند — چیدمان هنوز بارگذاری نشده و عناصر View در سلسله‌مراتب وجود ندارند. این یکی از رایج‌ترین خطاهای توسعه‌دهندگان مبتدی Android است.

onCreate در Fragment

onCreate در Fragment با Activity متفاوت است: در اینجا setContentView فراخوانی نمی‌شود و فقط مقداردهی اولیه داده‌های غیرمرتبط با UI انجام می‌شود. Fragment ایجاد کامپوننت و ایجاد 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 تقریباً به ۵۰۰ کیلوبایت محدود است — تجاوز از حد باعث ایجاد استثنای 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 بیش از ۵ ثانیه طول بکشد، سیستم یک دیالوگ ANR (Application Not Responding) نشان می‌دهد و به کاربر پیشنهاد بستن برنامه را می‌دهد. عملیات طولانی مانند بارگذاری داده از شبکه یا خواندن از پایگاه داده باید به رشته پس‌زمینه منتقل شوند.

طبق توصیه‌های Google Android Performance (2025)، onCreate باید در کمتر از ۱ ثانیه در دستگاه‌های میان‌رده به پایان برسد. برای این منظور باید: از مقداردهی اولیه تنبل (delegate lazy در Kotlin) استفاده کنید، بارگذاری داده‌های سنگین را به onResume یا از طریق کوروتین‌ها به تعویق بیندازید، از ViewStub برای کامپوننت‌های 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 شما از ۵۰۰ میلی‌ثانیه بیشتر شود، کنسول آن را به عنوان مشکل عملکرد علامت‌گذاری می‌کند. ما در IT Sectr از تست‌های Macrobenchmark برای کنترل خودکار زمان راه‌اندازی هر Activity در خط لوله 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) با پشتیبانی از کوروتین‌ها واکنش‌گرایی را اضافه می‌کند. این معماری استانداردی است که Google در راهنمای Guide to App Architecture توصیه می‌کند.

خطاهای رایج در کار با onCreate

حتی توسعه‌دهندگان با تجربه در onCreate خطاهای معمولی مرتکب می‌شوند. بیایید پنج مشکل رایج و روش‌های اجتناب از آنها را بررسی کنیم.

کار با View قبل از setContentView

رایج‌ترین خطا — تلاش برای یافتن View از طریق findViewById قبل از فراخوانی setContentView. همه عناصر View در لحظه inflate چیدمان ایجاد می‌شوند، بنابراین هر مراجعه به findViewById قبل از setContentView null برمی‌گرداند و هنگام تلاش برای استفاده از View باعث NullPointerException می‌شود. راه‌حل: ترتیب دقیق — ابتدا super، سپس setContentView، بعد findViewById یا ViewBinding.

مسدود کردن رشته UI با عملیات طولانی

بارگذاری داده از شبکه، خواندن از پایگاه داده یا پردازش آرایه‌های بزرگ به‌طور مستقیم در onCreate رندر فریم اول را مسدود می‌کند. کاربر تا پایان یافتن onCreate یک صفحه سیاه می‌بیند که درک سرعت برنامه را کاهش می‌دهد. راه‌حل: برای عملیات ناهمگام از lifecycleScope.launch استفاده کنید، تا پایان بارگذاری یک اسکلتون (placeholder UI) نمایش دهید.

نادیده گرفتن savedInstanceState

اگر هنگام چرخش صفحه وضعیت از Bundle بازیابی نشود، کاربر تمام ورودی ذخیره‌نشده را از دست می‌دهد: متن در فیلدهای فرم، موقعیت اسکرول، عناصر انتخاب‌شده. راه‌حل: همیشه savedInstanceState != null را در onCreate برای بازیابی داده‌ها بررسی کنید، حتی اگر به نظر می‌رسد از دست دادن وضعیت بعید است.

نشت حافظه از طریق کلاس‌های ناشناس

کلاس‌های ناشناس و لامبداها در 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 را پرتاب می‌کند و برنامه crash می‌کند. سیستم به‌طور دقیق الزام می‌کند که هر متد بازنویسی‌شده چرخه حیات نسخه 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 باید در کمتر از ۱ ثانیه اجرا شود، عملیات طولانی به کوروتین‌ها منتقل می‌شوند
  • ViewModel — مقداردهی اولیه ViewModel در onCreate مشکل از دست رفتن داده هنگام چرخش صفحه را حل می‌کند
  • Fragment vs Activity — onCreate Fragment حاوی کد UI نیست، onCreate Activity چیدمان را از طریق setContentView بارگذاری می‌کند
  • پنج خطای رایج — کار با View قبل از setContentView، مسدود کردن UI، نادیده گرفتن Bundle، نشت حافظه، کد UI در Fragment.onCreate

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید