ภาพรวมของกระบวนการและชุดข้อความ

เมื่อคอมโพเนนต์ของแอปพลิเคชันเริ่มทำงานและแอปพลิเคชันไม่มีคอมโพเนนต์อื่นเลย ทำงาน ระบบ Android จะเริ่มต้นกระบวนการใหม่ของ Linux สำหรับแอปพลิเคชัน ด้วยเธรดเดียว โดยค่าเริ่มต้น คอมโพเนนต์ทั้งหมดของแอปพลิเคชันเดียวกัน จะทำงานในกระบวนการและเทรดเดียวกัน ซึ่งเรียกว่าชุดข้อความหลัก

หากคอมโพเนนต์ของแอปพลิเคชันเริ่มต้นขึ้นและมีกระบวนการอยู่แล้ว สำหรับแอปพลิเคชันนั้น เนื่องจากคอมโพเนนต์อื่นจากแอปพลิเคชันได้เริ่มทำงานแล้ว จะเริ่มต้นภายในกระบวนการดังกล่าวและใช้เธรดการดำเนินการเดียวกัน อย่างไรก็ตาม คุณสามารถจัดให้มี คอมโพเนนต์ต่างๆ ในแอปพลิเคชันของคุณเพื่อเรียกใช้ในกระบวนการที่แยกจากกัน และคุณสามารถสร้าง ชุดข้อความสำหรับทุกกระบวนการ

เอกสารฉบับนี้กล่าวถึงวิธีการทำงานของกระบวนการและชุดข้อความในแอปพลิเคชัน Android

กระบวนการ

โดยค่าเริ่มต้น คอมโพเนนต์ทั้งหมดของแอปพลิเคชันจะทำงานในกระบวนการเดียวกัน และแอปพลิเคชันส่วนใหญ่ ไม่ต้องเปลี่ยนแปลง แต่ถ้าคุณพบว่าคุณต้องควบคุมกระบวนการบางอย่าง เป็นของ คุณสามารถทำได้ในไฟล์ Manifest

รายการไฟล์ Manifest สำหรับองค์ประกอบคอมโพเนนต์แต่ละประเภท ได้แก่ <activity>, <service>, <receiver> และ <provider> รองรับแอตทริบิวต์ android:process ที่ระบุแอตทริบิวต์ ที่คอมโพเนนต์จะทำงาน คุณสามารถตั้งค่าแอตทริบิวต์นี้เพื่อให้คอมโพเนนต์แต่ละรายการทำงาน ในกระบวนการของตนเอง หรือเพื่อให้คอมโพเนนต์บางส่วนใช้กระบวนการร่วมกันแต่บางรายการไม่ได้ใช้

นอกจากนี้ คุณยังสามารถตั้งค่า android:processเพื่อให้คอมโพเนนต์ของแอปพลิเคชันต่างๆ ทำงานเหมือนกัน หากแอปพลิเคชันใช้ User-ID ของ Linux เดียวกันและลงชื่อด้วย ใบรับรองเดียวกัน

<application> ยังสนับสนุนแอตทริบิวต์ android:process ที่คุณสามารถใช้เพื่อตั้งค่า ค่าเริ่มต้นที่ใช้กับคอมโพเนนต์ทั้งหมด

Android อาจตัดสินใจปิดกระบวนการในบางจุดเมื่อมีทรัพยากร ที่จำเป็นโดยกระบวนการอื่นๆ ที่ให้บริการกับผู้ใช้โดยทันทีมากกว่า การสมัคร คอมโพเนนต์ที่ทำงานในกระบวนการปิดตัวก็จะถูกทำลายไปด้วย เริ่มกระบวนการแล้ว อีกครั้งสำหรับคอมโพเนนต์เหล่านั้น เมื่อมีงานต้องทำ

เมื่อตัดสินใจว่าจะปิดกระบวนการใด ระบบ Android จะให้น้ำหนักความสำคัญที่เกี่ยวข้องกับกระบวนการเหล่านั้น ผู้ใช้รายนั้น ตัวอย่างเช่น ปิดกระบวนการที่โฮสต์กิจกรรมซึ่งไม่ได้ใช้แล้ว แสดงบนหน้าจอ เทียบกับกระบวนการที่โฮสต์กิจกรรมที่มองเห็นได้ การตัดสินใจว่าจะ การสิ้นสุดกระบวนการจึงขึ้นอยู่กับสถานะของคอมโพเนนต์ที่ทำงานอยู่ในกระบวนการนั้น

รายละเอียดของวงจรกระบวนการและความสัมพันธ์กับสถานะของแอปพลิเคชันจะมีการอธิบายไว้ใน กระบวนการและวงจรของแอป

ชุดข้อความ

เมื่อเปิดแอปพลิเคชัน ระบบจะสร้างเธรดการดำเนินการสำหรับแอปพลิเคชัน ซึ่งเรียกว่าชุดข้อความหลัก ชุดข้อความนี้มีความสำคัญมาก เนื่องจากมีหน้าที่ในการส่งเหตุการณ์ไปยัง วิดเจ็ตอินเทอร์เฟซผู้ใช้ที่เหมาะสม รวมถึงเหตุการณ์การวาดภาพ และยัง เทรดที่แอปพลิเคชันโต้ตอบกับคอมโพเนนต์เกือบทุกครั้ง จาก android.widget ของชุดเครื่องมือ Android UI และ android.view แพ็กเกจ ด้วยเหตุนี้ บางครั้งเทรดหลักจึง ซึ่งเรียกว่าชุดข้อความ UI อย่างไรก็ตาม ภายใต้สถานการณ์พิเศษ หน้าหลักของแอป เทรดอาจไม่ใช่เทรด UI ของเทรด ดูข้อมูลเพิ่มเติมได้ที่ชุดข้อความ คำอธิบายประกอบ

ระบบจะไม่สร้างชุดข้อความแยกสำหรับแต่ละอินสแตนซ์ของคอมโพเนนต์ ทั้งหมด คอมโพเนนต์ที่ทำงานในกระบวนการเดียวกันจะมีการสร้างอินสแตนซ์ในเทรด UI และการเรียกใช้ระบบไปยัง คอมโพเนนต์แต่ละรายการจะส่งมาจากชุดข้อความนั้น ดังนั้น วิธีการต่างๆ ที่ตอบสนองต่อระบบ Callback เช่น onKeyDown() เพื่อรายงานการดำเนินการของผู้ใช้หรือเมธอด Callback สำหรับวงจรจะทำงานในเธรด UI ของกระบวนการเสมอ

ตัวอย่างเช่น เมื่อผู้ใช้แตะปุ่มบนหน้าจอ ชุดข้อความ UI ของแอปจะส่งฟังก์ชัน กิจกรรมที่แตะกับวิดเจ็ต ซึ่งจะตั้งสถานะที่มีการกดค้างและโพสต์คำขอให้เป็นโมฆะ คิวเหตุการณ์ ชุดข้อความ UI จะจัดคิวคำขอและแจ้งให้วิดเจ็ตวาดใหม่ โดยตรง

เว้นแต่คุณจะใช้งานแอปพลิเคชันอย่างถูกต้อง รูปแบบเธรดเดี่ยวนี้ อาจให้ประสิทธิภาพที่ไม่ดีเมื่อแอปต้องทำงานอย่างหนักเพื่อตอบสนองต่อการโต้ตอบของผู้ใช้ การดำเนินการที่ใช้เวลานานในเทรด UI เช่น การเข้าถึงเครือข่ายหรือ การค้นหาฐานข้อมูล บล็อกทั้ง UI เมื่อชุดข้อความถูกบล็อกแล้ว จะส่งกิจกรรมไม่ได้ เช่น กิจกรรมการวาดภาพ

จากมุมมองของผู้ใช้ เหมือนว่าแอปพลิเคชันค้าง ยิ่งไปกว่านั้น หากเทรด UI ถูกบล็อกนานกว่า 2-3 วินาที ผู้ใช้เห็น "แอปพลิเคชัน ตอบกลับ" (ANR) ผู้ใช้อาจตัดสินใจปิดแอปพลิเคชันหรือถอนการติดตั้ง ได้

โปรดทราบว่าชุดเครื่องมือ Android UI ไม่ไม่ปลอดภัยสำหรับเทรด ดังนั้นอย่าดำเนินการใดๆ UI จากเธรดผู้ปฏิบัติงาน จัดการอินเทอร์เฟซผู้ใช้ทั้งหมดจาก UI ชุดข้อความ รูปแบบชุดข้อความเดียวของ Android มีกฎ 2 ข้อดังนี้

  1. อย่าบล็อกชุดข้อความ UI
  2. อย่าเข้าถึงชุดเครื่องมือ Android UI จากภายนอกชุดข้อความ UI

ชุดข้อความของผู้ปฏิบัติงาน

และเนื่องจากรูปแบบชุดข้อความเดียวนี้ จำเป็นต่อการตอบสนอง UI ของแอปพลิเคชันที่คุณไม่บล็อกเทรด UI หากคุณมีการดำเนินงานที่ต้องดำเนินการ ที่ไม่เกิดขึ้นทันที ให้ตรวจสอบว่าได้ทำในพื้นหลังแยกต่างหากหรือ worker อย่าลืมว่าคุณไม่สามารถอัปเดต UI จากชุดข้อความอื่นๆ ได้ UI หรือเทรดหลัก

Android มีหลายวิธีในการเข้าถึงชุดข้อความ UI จาก ชุดข้อความ รายการวิธีการที่สามารถช่วยได้:

ตัวอย่างต่อไปนี้ใช้ View.post(Runnable)

Kotlin

fun onClick(v: View) {
    Thread(Runnable {
        // A potentially time consuming task.
        val bitmap = processBitMap("image.png")
        imageView.post {
            imageView.setImageBitmap(bitmap)
        }
    }).start()
}

Java

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            // A potentially time consuming task.
            final Bitmap bitmap =
                    processBitMap("image.png");
            imageView.post(new Runnable() {
                public void run() {
                    imageView.setImageBitmap(bitmap);
                }
            });
        }
    }).start();
}

การใช้งานนี้ปลอดภัยของเทรด เนื่องจากการดำเนินการในเบื้องหลังนั้นดำเนินการจากเทรดที่แยกต่างหาก ในขณะที่ ImageView จะถูกจัดการจากเธรด UI เสมอ

อย่างไรก็ตาม เมื่อความซับซ้อนของการดำเนินการเพิ่มขึ้น โค้ดประเภทนี้อาจซับซ้อนและ ที่ดูแลได้ยาก หากต้องการจัดการการโต้ตอบที่ซับซ้อนยิ่งขึ้นกับชุดข้อความของพนักงาน คุณอาจลองพิจารณา ใช้ Handler ในชุดข้อความสำหรับผู้ปฏิบัติงานของคุณ เพื่อประมวลผลข้อความที่ส่งจาก ชุด UI หากต้องการดูคำอธิบายโดยละเอียด กำหนดเวลาการทำงานบนเธรดในเบื้องหลังและสื่อสารกลับไปยังเธรด UI โปรดดู ภาพรวมของงานที่ทำอยู่เบื้องหลัง

วิธีการที่ปลอดภัยของชุดข้อความ

ในบางสถานการณ์ ระบบจะเรียกเมธอดที่คุณใช้จากชุดข้อความมากกว่า 1 รายการ และ จึงต้องเขียนให้เหมาะสำหรับชุดข้อความ

โดยหลักแล้วมีไว้สำหรับเมธอดที่เรียกใช้จากระยะไกลได้ เช่น เมธอดในบริการที่มีผลผูกพัน เมื่อมีการโทรหาหมายเลข ที่ใช้ใน IBinder จะเริ่มต้นในกระบวนการเดียวกับที่เมธอด IBinder ทำงานอยู่ วิธีการนี้ดำเนินการในชุดข้อความของผู้โทร อย่างไรก็ตาม เมื่อการเรียกเกิดขึ้นในกระบวนการอื่น เมธอดจะทำงานในเทรดที่เลือกไว้ กลุ่มเทรดที่ระบบเก็บรักษาไว้ในกระบวนการเดียวกันกับ IBinder ไม่ได้ดำเนินการในเธรด UI ของกระบวนการ

ตัวอย่างเช่น ขณะที่บริการ มีการเรียกเมธอด onBind() จากเธรด UI ของ ประมวลผล เมธอดที่ใช้ในออบเจ็กต์ที่ onBind() แสดงผล เช่น ระบบจะเรียกคลาสย่อยที่ใช้เมธอดการเรียกโพรซีเยอร์ระยะไกล (RPC) จากเทรด ในสระว่ายน้ำ เนื่องจากบริการหนึ่งๆ มีไคลเอ็นต์มากกว่า 1 ราย ชุดข้อความในพูลจึงมีส่วนร่วมได้มากกว่า 1 รายการ เมธอด IBinder เดียวกันในเวลาเดียวกัน ดังนั้นเมธอด IBinder จึงต้อง มาใช้เพื่อให้เป็นความปลอดภัยของชุดข้อความ

ในทํานองเดียวกัน ผู้ให้บริการเนื้อหาสามารถรับคําขอข้อมูลที่เกิดขึ้นจากกระบวนการอื่นๆ ได้ ContentResolver และ ContentProvider คลาสจะซ่อนรายละเอียดวิธีจัดการการสื่อสารระหว่างโปรเซส (IPC) แต่ ContentProvider เมธอดที่ตอบสนองต่อคำขอเหล่านั้น เมธอด query(), insert(), delete(), update() และgetType()คือ เรียกจากกลุ่มชุดข้อความในกระบวนการของผู้ให้บริการเนื้อหา ไม่ใช่ UI เทรดสำหรับกระบวนการดังกล่าว เนื่องจากวิธีการเหล่านี้อาจมีการเรียกจากชุดข้อความจำนวนเท่าใดก็ได้ที่ ในเวลาเดียวกันก็ต้องนำไปใช้เพื่อให้ ชุดข้อความปลอดภัย

การสื่อสารระหว่างโปรเซส

Android มีกลไกสำหรับ IPC ที่ใช้ RPC ซึ่งกิจกรรมหรือแอปพลิเคชันอื่นๆ เรียกใช้เมธอด แต่ดำเนินการจากระยะไกลในกระบวนการอื่น โดยส่งคืนผลลัพธ์กลับไปยัง ของผู้โทร ซึ่งจะทำให้เกิดการแยกการเรียกเมธอดและข้อมูลของการเรียกในระดับที่ระบบปฏิบัติการสามารถกระทำได้ ทำความเข้าใจ ส่งผ่านกระบวนการจากกระบวนการภายในพื้นที่และระบุพื้นที่ไปยังกระบวนการระยะไกล และ ของที่อยู่นี้ แล้วประกอบขึ้นมาใหม่และดำเนินการเรียกใช้ในที่นั้น

ผลลัพธ์จะดังนี้ ที่ถูกส่งไปในทิศทางตรงกันข้าม Android มีโค้ดทั้งหมดเพื่อทำ IPC เหล่านี้ ธุรกรรม ดังนั้นคุณจะสามารถมุ่งเน้นที่การกำหนดและการนำอินเทอร์เฟซการเขียนโปรแกรม RPC มาใช้ได้

หากต้องการดำเนินการ IPC แอปพลิเคชันของคุณจะต้องเชื่อมโยงกับบริการโดยใช้ bindService() ดูข้อมูลเพิ่มเติมได้ที่ภาพรวมของบริการ