ความแตกต่างระหว่างบริบทของกิจกรรมและบริบทของแอปพลิเคชัน


233

สิ่งนี้ทำให้ฉันนิ่งงันฉันใช้สิ่งนี้กับ Android 2.1-r8 SDK:

ProgressDialog.show(getApplicationContext(), ....);

และใน

Toast t = Toast.makeText(getApplicationContext(),....);

ใช้getApplicationContext()ล่มทั้งสองProgressDialogและToast.... ซึ่งทำให้ฉันคำถามนี้:

อะไรคือความแตกต่างที่เกิดขึ้นจริงระหว่างบริบทของกิจกรรมและบริบทของแอปพลิเคชันแม้จะแบ่งปันคำว่า 'บริบท'


นี่คือสิ่งที่ฉันได้พบstackoverflow.com/questions/1561803/… ....
t0mm13b

14
สิ่งนี้จะช่วยล้างบางสิ่ง: บริบทบริบทอะไร
toobsco42

คำตอบ:


250

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

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

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

แต่โดยทั่วไปให้ใช้บริบทของกิจกรรมหากคุณไม่มีเหตุผลที่ดี


1
ฉันได้รับ 'java.lang.reflect.InvocationTargetException' เมื่อใช้getApplicationContextน่าสนใจพอเมื่อฉันเปลี่ยนเป็นthisมันไม่ได้ผิดพลาดและทำงานตามที่คาดไว้ .... ดังนั้นหากพวกเขาทั้งสองกรณีของบริบททำไมหนึ่งไม่ทำงานและ อื่น ๆ ทำอย่างไร ข้อมูลนี้จะช่วยคนอื่น ๆ ฉันหวังว่า ... :) ขอบคุณสำหรับคำตอบที่รวดเร็วของคุณ ...
t0mm13b

2
ฉันต้องการเห็นข้อยกเว้นสแต็คเต็มสแต็คเพื่อให้สามารถพูดอะไรได้ อย่างไรก็ตามอย่างที่บอกไปว่าอินสแตนซ์บริบทมีข้อมูลที่ต่างกัน สันนิษฐานว่าแสดงกล่องโต้ตอบหรือขนมปังบนหน้าจอต้องใช้ข้อมูลเกี่ยวกับกิจกรรมที่มีเพียงอินสแตนซ์ของกิจกรรมเท่านั้น
Cheryl Simon

74
ฉันจะบอกว่าใช้บริบทของแอพเว้นแต่คุณจะมีเหตุผลที่ดีไม่มากเกินไป (เช่นสำหรับไดอะล็อกหรือขนมปังปิ้ง) มันค่อนข้างง่ายที่จะเรียกใช้การรั่วไหลของหน่วยความจำโดยใช้บริบทของกิจกรรมในสถานการณ์ที่แตกต่างกันดังนั้นควรปลอดภัย :) android-developers.blogspot.com/2009/01//
Dori

10
เดฟสมิ ธ ได้โพสต์รายการบล็อกที่ดีมากสำหรับการทำความเข้าใจการใช้งานของบริบทให้ดูที่นี่ ตรวจสอบให้แน่ใจว่าคุณได้อ่านความคิดเห็น!
ChrLipp

1
ประเด็นก็คือแม้กระทั่ง Dianna Hackborn ก็แนะนำให้ใช้บริบทของกิจกรรม stackoverflow.com/questions/5228160/…แต่ดูเหมือนว่าเธอจะไม่แน่ใจในเรื่องนี้ทั้งหมด
JacksOnF1re

178

ฉันพบว่าตารางนี้มีประโยชน์มากสำหรับการตัดสินใจว่าจะใช้บริบทประเภทต่างๆเมื่อใด:

ป้อนคำอธิบายรูปภาพที่นี่

  1. แอปพลิเคชันสามารถเริ่มกิจกรรมได้จากที่นี่ แต่ต้องการให้สร้างงานใหม่ สิ่งนี้อาจเหมาะกับกรณีการใช้งานเฉพาะ แต่สามารถสร้างพฤติกรรมการสแต็กกลับที่ไม่ได้มาตรฐานในแอปพลิเคชันของคุณและโดยทั่วไปจะไม่แนะนำหรือถือว่าเป็นแนวปฏิบัติที่ดี
  2. สิ่งนี้เป็นสิ่งถูกกฎหมาย แต่เงินเฟ้อจะทำกับธีมเริ่มต้นสำหรับระบบที่คุณใช้งานไม่ใช่สิ่งที่กำหนดไว้ในแอปพลิเคชันของคุณ
  3. อนุญาตถ้าผู้รับเป็นโมฆะซึ่งใช้สำหรับรับค่าปัจจุบันของการออกอากาศแบบติดหนึบบน Android 4.2 ขึ้นไป

บทความต้นฉบับที่นี่


2
ที่เก็บถาวรของบทความweb.archive.org/web/20150329210012/https://possiblemobile.com/…
nmu

แล้วการรับทรัพยากรล่ะ ฉันคิดว่าคุณควรเพิ่มมันเข้าไปในตารางของคุณ และคุณสามารถเข้าถึงทรัพยากรโดยใช้บริบทการจัดเรียง
Amir Ziarati

เราสามารถเริ่มกิจกรรมจากบริบทของแอปพลิเคชัน
Duy Phan

บทความสามารถพบได้ที่นี่: wundermanthompsonmobile.com/2013/06/context
Lifes

34

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


25
เห็นด้วยอย่างสมบูรณ์ Google ปล่อยลูกบอลบนอันนี้ มันเป็นระเบียบสมบูรณ์
Søren Boisen

@ SørenBoisen android sdk เป็นระเบียบที่สมบูรณ์
CommonSenseCode

พวกเขาตระหนักถึงความยุ่งเหยิงและมั่นใจว่าพวกเขากำลังดิ้นรนอย่างหนักเพื่อแก้ไขให้ได้มากที่สุด
pasignature

15

เหตุผลที่ฉันคิดว่าเป็นสิ่งที่ProgressDialogแนบมากับกิจกรรมที่ประกอบขึ้นProgressDialogเป็นกล่องโต้ตอบไม่สามารถอยู่หลังจากที่กิจกรรมจะถูกทำลายดังนั้นมันจะต้องผ่านthis(ActivityContext) ที่ยังถูกทำลายด้วยกิจกรรมในขณะที่ ApplicationContext ยังคงอยู่แม้หลังจากกิจกรรม ทำลาย


3

ใช้ getApplicationContext () หากคุณต้องการบางสิ่งที่เชื่อมโยงกับบริบทที่ตัวเองจะมีขอบเขตทั่วโลก

หากคุณใช้กิจกรรมอินสแตนซ์กิจกรรมใหม่จะมีการอ้างอิงซึ่งมีการอ้างอิงโดยนัยไปยังกิจกรรมเก่าและกิจกรรมเก่าไม่สามารถรวบรวมขยะได้


2

ฉันคิดว่าเมื่อทุกอย่างต้องการหน้าจอที่จะแสดง (ปุ่ม, ข้อความ, เลย์เอาต์ ... ) เราต้องใช้กิจกรรมบริบทและทุกอย่างไม่จำเป็นต้องมีหน้าจอเพื่อแสดงหรือประมวลผล (ขนมปังปิ้ง, บริการโทรศัพท์, ติดต่อ ... ) เรา สามารถใช้บริบทแอปพลิเคชัน


1

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

นี่คือตัวอย่างการใช้งานจริงของสิ่งที่ "พฤติกรรมสแต็กหลังที่ไม่ได้มาตรฐาน" ที่กล่าวถึงโดย @CommonSenseCode หมายถึง:

สมมติว่าคุณมีสองปพลิเคชันที่สื่อสารกับแต่ละอื่น ๆApp1และApp2

เรียกใช้App2: MainActivityจากตัวเรียกใช้งาน จากนั้นก็เปิดตัว MainActivity App2: SecondaryActivity ทั้งที่ใช้บริบทของกิจกรรมหรือบริบทของแอปพลิเคชันกิจกรรมทั้งสองอยู่ในภารกิจเดียวกันและไม่เป็นไร (เนื่องจากคุณใช้โหมดเรียกใช้มาตรฐานและแฟล็กเจตนา) คุณสามารถกลับไปที่ MainActivity ด้วยการกดย้อนกลับและในแอพล่าสุดที่คุณมีเพียงงานเดียว

สมมติว่าคุณอยู่ในApp1และเปิดใช้App2: MainActivityโดยมีจุดประสงค์ในการแชร์ (ACTION_SEND หรือ ACTION_SEND_MULTIPLE) จากนั้นให้ลองเรียกใช้App2: SecondaryActivity (ทุกครั้งที่มีโหมดการเปิดใช้มาตรฐานและค่าสถานะความตั้งใจ) เกิดอะไรขึ้น:

  • หากคุณเปิดใช้งาน App2: กิจกรรมรองพร้อมบริบทแอปพลิเคชันบน Android <10 คุณจะไม่สามารถเปิดกิจกรรมทั้งหมดในงานเดียวกันได้ ฉันได้ลองกับ android 7 และ 8 และ SecondaryActivity เปิดตัวเสมอในงานใหม่ (ฉันเดาว่าเป็นเพราะ App2: SecondaryActivity เปิดตัวด้วยบริบทแอปพลิเคชัน App2 แต่คุณมาจาก App1 และคุณไม่ได้เปิดแอปพลิเคชัน App2 โดยตรง . ภายใต้ประทุน Android ยอมรับว่าและใช้ FLAG_ACTIVITY_NEW_TASK) สิ่งนี้อาจดีหรือไม่ดีขึ้นอยู่กับความต้องการของคุณสำหรับใบสมัครของฉันไม่ดี
    บน Android 10 แอปขัดข้องด้วยข้อความ
    "การโทร startActivity () จากด้านนอกของบริบทกิจกรรมต้องมีการตั้งค่าสถานะ FLAG_ACTIVITY_NEW_TASK นี่คือสิ่งที่คุณต้องการจริงหรือ" .
    ดังนั้นเพื่อให้มันทำงานบน Android 10 คุณต้องใช้ FALG_ACTIVITY_NEW_TASK และคุณไม่สามารถเรียกใช้กิจกรรมทั้งหมดในงานเดียวกัน
    ในขณะที่คุณสามารถดูพฤติกรรมที่แตกต่างระหว่างรุ่น Android แปลก

  • หากคุณเปิดใช้งาน App2: กิจกรรมรองพร้อมบริบทของกิจกรรมทั้งหมดเป็นไปด้วยดีและคุณสามารถเรียกใช้กิจกรรมทั้งหมดในภารกิจเดียวกันทำให้เกิดการนำทางแบ็คสแต็คเชิงเส้น

ฉันหวังว่าฉันได้เพิ่มข้อมูลที่เป็นประโยชน์บางอย่าง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.