onStart: สาระ, การมองเห็น Activity บนหน้าจอ Android

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-03-04 เวลาอ่าน: 9 นาที

onStart เป็นเมธอดวงจรของ Android ที่ถูกเรียกเมื่อ Activity หรือ Fragment เป็นที่เห็นสำหรับผู้ใช้ ในขณะนี้, หน้าจอจะปรากณ์บนหน้าจอของอุปกรณ์ แต่ยังไม่สามารถโต้ตอบกับผู้ใช้ได้ — โฟกัสการใส่ข้อมูลจะไม่มีจนกว่าจะมีการเรียก onResume เมธอด onStart เหมาะสำหรับการลงทะเบียนผู้ฟังระบบ, เชื่อมต่อบริการตำแหน่งที่ตั้งทางภูมิศาสตร์ และเริ่มแอนิเมชันที่ควรทำงานในขณะที่ส่วนประกอบมองเห็นบนหน้าจอ เรียนรู้เพิ่มเติมเกี่ยวกับวงจร Activity ที่สมบูรณ์ได้ในบทความ Activity Lifecycle

หัวข้อสำคัญ

  • onStart — เรียกเมื่อ Activity หรือ Fragment มองเห็นบนหน้าจอ; มาก่อน onResume
  • การลงทะเบียนผู้ฟัง — BroadcastReceiver, LocationListener, SensorListener ลงทะเบียนใน onStart และยกเลิกใน onStop
  • แอนิเมชัน — เริ่มแอนิเมชันที่ควรทำงานในขณะที่หน้าจอมองเห็น; หยุดชั่วคราวใน onStop
  • บริการแบบผูก — เชื่อมต่อบริการไคลเอนต์-เซิร์ฟเวอร์ผ่าน bindService ใน onStart, ตัดการเชื่อมต่อใน onStop
  • onStart vs onResume — onStart = การมองเห็น, onResume = โฟกัส + การโต้ตอบ; ระดับกิจกรรมหน้าจอที่แตกต่างกัน
  • Fragment.onStart — เรียกหลัง Activity.onStart, เมื่อ Fragment มองเห็นในคอนเทนเนอร์
  • คู่ onStart/onStop — ทรัพยากรที่เชื่อมต่อใน onStart ต้องปล่อยใน onStop เพื่อป้องกันการรั่วไหล

สาระของ onStart ใน Android

onStart เป็นเมธอดที่สองของวงจร Activity, เรียกโดยระบบหลัง onCreate (หรือหลัง onRestart เมื่อกลับจากสถานะหยุด) ในขณะที่เรียก onStart, Activity หรือ Fragment จะมองเห็นบนหน้าจอ ผู้ใช้จะเห็นส่วนติดต่อประสานงาน แต่หน้าจอยังไม่พร้อมสำหรับการโต้ตอบ — โฟกัสการใส่ข้อมูลจะปรากณ์หลัง onResume เท่านั้น

เมธอด onStart เป็นส่วนของ “อายุที่มองเห็น” (visible lifetime) ของ Activity — ช่วงระหว่าง onStart และ onStop ในช่วงนี้, Activity อาจถูกปกคลุมบางส่วนโดยหน้าต่างๆ (เช่น Activity โปร่งใส หรือหน้าต่างโต้ตอบ) แต่ UI ของมันยังคงมองเห็นได้ นี่แยกความแตกต่างระหว่างอายุที่มองเห็นและ “อายุที่เบื้องหน้า” (onResume — onPause) เมื่อ Activity มีโฟกัสการใส่ข้อมูลเต็มที่

การเข้าใจลำดับชั้นสามระดับนี้มีความสำคัญอย่างยิ่งสำหรับการแจกจ่ายโค้ดอย่างถูกต้อง onCreate — การเริ่มต้นครั้งเดียว, onStart — การเชื่อมต่อทรัพยากรที่มองเห็น, onResume — การเข้าถึงแอบประเภททรัพยากรที่เฉพาะ นักพัฒนาที่สับสนระดับเหล่านี้เสี่ยงต่อการสร้างหน่วยความจำรั่วไหลหรือพฤติกรรมแอปพลิเคชันที่ไม่ถูกต้องเมื่อสลับระหว่างหน้าจอ

onStart ใน Activity

ใน Activity, เมธอด onStart จะถูกเรียกทุกครั้งที่หน้าจอปรากณ์บนหน้าจอแสดงผล — ทั้งเมื่อเริ่มต้นครั้งแรก (หลัง onCreate) และเมื่อกลับมาจากภูมหลัง (หลัง onRestart) แตกต่างจาก onCreate, onStart สามารถเรียกได้หลายครั้งตลอดอายุของอินสแตนซ์ Activity ดังนั้นโค้ดที่ต้องทำงานทุกครั้งที่หน้าจอปรากณ์จะถูกวางไว้ที่นี่

kotlin
class DashboardActivity : AppCompatActivity() {
    private val connectivityReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            val isConnected = ... // ตรวจสอบ ConnectivityManager
            binding?.statusIndicator?.setColor(
                if (isConnected) Color.GREEN else Color.RED
            )
        }
    }

    override fun onStart() {
        super.onStart()
        registerReceiver(
            connectivityReceiver,
            IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
        )
        SensorManager.getInstance().registerStepCounter()
    }

    override fun onStop() {
        unregisterReceiver(connectivityReceiver)
        SensorManager.getInstance().unregisterStepCounter()
        super.onStop()
    }
}

กฏข้อเด็ดขาด: ทรัพยากรที่เชื่อมต่อใน onStart ทั้งหมดต้องปล่อยใน onStop นี่ทำให้แน่ใจว่าเมื่อ Activity ถูกซ่อนจากหน้าจอ, มันจะไม่ใช้แบตเตอรี่, ไม่ฟังกิจกรรมระบบ และไม่ใช้หน่วยความจำ Android Studio มีกฏข้อ lint ที่เตือนเกี่ยวกับการลงทะเบียน BroadcastReceiver โดยไม่มีการยกเลิกที่สอดคล้องกัน

onStart ใน Fragment

onStart ใน Fragment เชื่อมโยงกับวงจรของ Activity ที่เป็นเจ้าภาพ Fragment จะได้รับการเรียก onStart หลังจากที่ Activity ที่เป็นเจ้าภาพได้รับ onStart แล้ว อย่างไรก็ตาม, หาก Fragment ถูกเพิ่มในโหมดรอ (ไม่มี addToBackStack ใน FragmentTransaction.commit()) onStart อาจถูกเรียกด้วยความล่าช้า

kotlin
class MapFragment : Fragment() {
    private var mapView: MapView? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        mapView = MapView(requireContext())
        return mapView!!
    }

    override fun onStart() {
        super.onStart()
        mapView?.onStart()
        LocationService.connect(requireContext())
    }

    override fun onStop() {
        mapView?.onStop()
        LocationService.disconnect()
        super.onStop()
    }
}

ข้อเฉพาะของ Fragment.onStart: หาก Fragment อยู่ใน ViewPager ที่มี offscreenPageLimit = 1, แฟรกมินต์ใกล้เคียงจะได้รับ onStart เช่นกันก่อนที่จะมองเห็น ซึ่งอาจนำไปสู่การลงทะเบียนผู้ฟังก่อนกำหนด สำหรับกรณีเช่นนี้, ใช้เมธอด setUserVisibleHint() หรือตรวจสอบ isVisible ภายใน onStart เพื่อลงทะเบียนผู้ฟังเฉพาะสำหรับแฟรกมินต์ที่มองเห็นจริง

ความแตกต่างระหว่าง onStart และ onResume

ความแตกต่างหลักระหว่าง onStart และ onResume คือระดับกิจกรรมของหน้าจอ onStart บ่งบอกว่า Activity มองเห็นบนหน้าจอ แต่ไม่จำเป็นต้องอยู่ในเบื้องหน้า onResume บ่งบอกว่า Activity อยู่ในเบื้องหน้าและมีโฟกัสการใส่ข้อมูล ความแตกต่างจะแสดงให้เห็นโดยตัวอย่างหน้าต่างโต้ตอบ: เมื่อ Dialog ปรากณ์เหนือ Activity, Activity จะสูญเสีย onResume (เรียก onPause) แต่ยังคงมองเห็นได้ — onStart/onStop ไม่ถูกเรียก

ตารางเปรียบเทียบแสดงอย่างชัดเจนว่าในสถานการณ์ใดที่แต่ละเมธอดถูกเรียก:

สถานการณ์onStartonResume
เริ่มแอปพลิเคชันเรียกเรียก
Dialog เปิดเหนือ Activityไม่เรียกonPause (สูญเสียโฟกัส)
กดปุ่ม HomeonStop (ซ่อน)onPause → onStop
กลับจากรายการล่าสุดonStart (มองเห็น)onResume (โฟกัส)
หมุนหน้าจอonCreate → onStart→ onResume
สายเข้าonStop (ซ่อน)onPause → onStop

ตารางนี้ช่วยให้นักพัฒนาตัดสินใจว่าควรวางโค้ดเฉพาะในเมธอดไหน ตัวอย่างเช่น, หากแอปพลิเคชันต้องหยุดการเล่นวิดีโอในทุกครั้งที่มีการซ้อนทับหน้าจอ (แม้แต่โต้ตอบ), โค้ดจะถูกวางใน onPause หากวิดีโอควรหยุดเมื่อหน้าจอถูกซ่อนอย่างสมบูรณ์ — โค้ดจะถูกวางใน onStop

การลงทะเบียนผู้ฟังและบริการ

onStart เป็นตำแหน่งที่เหมาะที่สุดสำหรับการลงทะเบียนผู้ฟังที่ควรทำงานเมื่อ Activity มองเห็นบนหน้าจอเท่านั้น ซึ่งประกอบด้วยส่วนประกอบระบบสามชนิดหลัก: BroadcastReceiver สำหรับกิจกรรมระบบ, LocationListener สำหรับการตำแหน่งที่ตั้งทางภูมิศาสตร์ และ SensorListener สำหรับเซ็นเซอร์ของอุปกรณ์

BroadcastReceiver ใน onStart

BroadcastReceiver ถูกลงทะเบียนแบบไดนามิกผ่าน Context.registerReceiver() ใน onStart และยกเลิกใน onStop ผ่าน unregisterReceiver() การลงทะเบียนแบบไดนามิกดีกว่าการลงทะเบียนแบบคงที่ (ใน manifest) เพราะมันจำกัดอายุของตัวรับไว้ในช่วงที่ Activity มองเห็น — แอปพลิเคชันจะไม่ตื่นจากข้อความ broadcast ของระบบเมื่อ Activity ถูกซ่อน

kotlin
private val batteryReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent) {
        val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
        binding?.batteryText?.text = "$level%"
    }
}

override fun onStart() {
    super.onStart()
    registerReceiver(batteryReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
}

override fun onStop() {
    unregisterReceiver(batteryReceiver)
    super.onStop()
}

LocationListener และ SensorListener

การตำแหน่งที่ตั้งทางภูมิศาสตร์และเซ็นเซอร์เป็นการณ์ที่ต้องใช้ทรัพยากรมาก การขออัพเดต GPS ใน onStart และยกเลิกใน onStop ช่วยให้แอปพลิเคชันไม่สิ้นแบตเตอรี่เมื่อหน้าจอถูกซ่อน สำหรับการปรับแต่งอย่างละเอียด, ใช้ requestLocationUpdates ด้วยช่วงห่างและระยะทางต่ำสุด — ตัวอย่าง, 10 วินาทีและ 10 เมตร ซึ่งให้ความสมดุลระหว่างความแม่นยำและการใช้พลังงาน

แอนิเมชันและ onStart

การเริ่มแอนิเมชันใน onStart แทนที่จะใน onCreate ช่วยให้แอนิเมชันเริ่มต้นทุกครั้งที่หน้าจอปรากณ์ หากคุณเริ่มแอนิเมชันใน onCreate, มันจะทำงานเฉพาะในการสร้าง Activity ครั้งแรก ไม่ใช่เมื่อกลับมาจากภูมหลัง onStart ถูกเรียกทุกครั้งที่ Activity มองเห็น ทำให้เป็นตำแหน่งที่เหมาะสำหรับเริ่มแอนิเมชันแบบวรรณจร และการเปลี่ยนผ่าน

kotlin
private lateinit var pulseAnimator: ValueAnimator

override fun onStart() {
    super.onStart()
    pulseAnimator.start()
    binding?.loadingIndicator?.animate()?.alpha(1f)?.start()
}

override fun onStop() {
    pulseAnimator.cancel()
    binding?.loadingIndicator?.animate()?.cancel()
    super.onStop()
}

สำหรับแอนิเมชันที่ใช้ ObjectAnimator หรือ ValueAnimator, สิ่งสำคัญคือการเรียก cancel() ใน onStop หากแอนิเมชันยังคงทำงานต่อไปหลังจากการซ่อน Activity, มันจะใช้ทรัพยากร GPU และ CPU โดยไม่จำเป็น, ทำให้ประสิทธิภาพของอุปกรณ์ลดลงและเร่งการสิ้นแบตเตอรี่ Android Studio Profiler (กราฟ GPU) ช่วยให้คุณติดตามแอนิเมชันที่ทำงานอยู่และตรวจจับการรั่วไหล

กฏข้อการจับคู่ onStart/onStop ยังใช้กับการทำงานกับกล้องสำหรับการแสดงตัวอย่าง (CameraX) การเปิดกล้องใน onStart และปิดใน onStop ช่วยให้แน่ใจว่ากล้องจะไม่ถูกบล็อกสำหรับแอปพลิเคชันอื่นเมื่อแอปพลิเคชันของคุณไม่มองเห็นบนหน้าจอ การละเมิดกฏข้อนี้เป็นสาเหตุทั่วไปของรีวิวเป็นลบใน Google Play

คำถามที่พบบ่อย

ความแตกต่างระหว่าง onStart และ onResume สำหรับการลงทะเบียนผู้ฟังคืออะไร?

onStart — สำหรับผู้ฟังที่ควรทำงานในขณะที่หน้าจอมองเห็น (BroadcastReceiver, LocationListener, SensorListener). onResume — สำหรับทรัพยากรที่ต้องการเข้าถึงแอบประเภท (กล้อง, การจับภาพวิดีโอ, การรู้จำเสียง). ผู้ฟังกิจกรรมระบบไม่ต้องการเข้าถึงแอบประเภทและสามารถทำงานได้แม้มีการซ้อนทับบางส่วน — พวกมันจะถูกลงทะเบียนใน onStart กล้องควรเปิดใช้งานเมื่อมีโฟกัสเต็มที่เท่านั้น — เปิดใน onResume

ทำไม onStart อาจไม่ถูกเรียก?

onStart จะถูกเรียกเสมอไปหาก Activity เข้าสู่สถานะที่มองเห็น สถานการณ์เดียวที่ไม่มี onStart คือ Activity ถูกสร้างและสิ้นสุดทันที (เช่น เนื่องจากข้อผิดพลาดใน onCreate) ในกรณีนี้, onDestroy จะถูกเรียกทันทีหลัง onCreate แต่นี่เป็นสถานการณ์ฉุกเฉินซึ่งไม่ควรเกิดขึ้นในโค้ดที่เขียนอย่างถูกต้อง

onStart สามารถถูกเรียกโดยไม่มี onResume ได้หรือไม่?

ได้, onStart อาจไม่ได้รับ onResume หาก Activity อื่นหรือหน้าต่างโปร่งใสเปิดทันทีเหนือ Activity ตัวอย่างเช่น, หากเปิดหน้าจออนุญาตหลัง onCreate (Activity A → Activity B), ใน Activity A onStart จะถูกเรียก แต่ onResume ไม่ — มันจะได้รับ onPause → onStop ทันทีเมื่อถูกซ้อนโดยหน้าจอ B

onStart สามารถถูกเรียกได้กี่ครั้ง?

onStart สามารถถูกเรียกได้ หลายครั้งตลอดอายุของอินสแตนซ์ Activity ทุกครั้งที่ Activity เปลี่ยนจากสถานะที่ซ่อน (onStop) ไปยังสถานะที่มองเห็น, onStart จะถูกเรียก ในทางปฏิบัติ, เมื่อใช้แอปพลิเคชันอย่างต่อเนื่อง, onStart สามารถถูกเรียกได้หลายสิบหรือหลายร้อยครั้งต่อเซสชั่น

ควรโหลดข้อมูลใน onStart หรือไม่?

การโหลดข้อมูลใน onStart มีเหตุผลหากข้อมูลจำเป็นต้องได้รับการอัพเดตทุกครั้งที่หน้าจอปรากณ์ ตัวอย่างเช่น, ฟีดข่าวหรือรายการแจ้งเตือน อย่างไรก็ตาม, การโหลดต้องเป็นแบบไม่ต้องประสานงานพร้อมกัน (แบบซิงค์โครนัส) — ผ่าน coroutine กับ lifecycleScope เพื่อไม่ให้บล็อกเธรด UI สำหรับข้อมูลที่ไม่เปลี่ยนแปลงระหว่างการปรากณ์ของหน้าจอ, การโหลดพียงครั้งเดียวใน onCreate ก็เพียงพอ

สรุป

  • onStart — เมธอดอายุที่มองเห็น; เรียกเมื่อ Activity หรือ Fragment ปรากณ์บนหน้าจอ
  • การลงทะเบียนใน onStart — BroadcastReceiver, LocationListener, SensorListener ลงทะเบียนใน onStart และยกเลิกใน onStop
  • onStart vs onResume — onStart = การมองเห็น, onResume = โฟกัสการใส่ข้อมูล; ระดับที่แตกต่างกันสำหรับประเภททรัพยากรที่แตกต่างกัน
  • แอนิเมชัน — เริ่มแอนิเมชันแบบวรรณจรใน onStart, หยุดใน onStop; ป้องกันการรั่วไหลทรัพยากร GPU
  • Fragment.onStart — เชื่อมโยงกับ Activity.onStart; ใน ViewPager เรียกล่วงหน้าสำหรับแฟรกมินต์ใกล้เคียง
  • กฏข้อการจับคู่ — ทรัพยากร onStart ทั้งหมดต้องปล่อยใน onStop, มิฉะนั้นจะเกิดการรั่วไหลหน่วยความจำและแบตเตอรี่
  • การโหลดข้อมูล — ใน onStart, โหลดข้อมูลที่ควรได้รับการอัพเดตทุกครั้งที่หน้าจอปรากณ์

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม