ความแตกต่างระหว่าง getContext (), getApplicationContext (), getBaseContext () และ“ this”


565

ความแตกต่างระหว่างคืออะไรgetContext(), getApplicationContext(), getBaseContext()และ " this"?

แม้ว่านี่เป็นคำถามง่าย ๆ ที่ฉันไม่สามารถเข้าใจความแตกต่างพื้นฐานระหว่างพวกเขา โปรดยกตัวอย่างง่ายๆถ้าเป็นไปได้


1
มีการเขียนที่ดีเยี่ยมในคำตอบแรกคือ: stackoverflow.com/questions/1026973/…
ky1enamic

คำตอบ:


528
  • View.getContext(): ส่งคืนบริบทที่มุมมองกำลังทำงานอยู่โดยปกติแล้วเป็นกิจกรรมที่ใช้งานอยู่ในปัจจุบัน

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

  • ContextWrapper.getBaseContext(): หากคุณต้องการเข้าถึงบริบทจากภายในบริบทอื่นคุณใช้ ContextWrapper บริบทที่อ้างถึงจากภายในซึ่งเข้าถึง ContextWrapper ผ่าน getBaseContext ()


59
และสิ่งที่เกี่ยวกับ "นี้"
coool i3oY

16
+ เพิ่ม i3oY ให้เหมือนกันกับ getContext
Mikey

13
จริงๆแล้วฉันสับสนว่าการกำหนดบริบทที่เหมาะสมคืออะไร?
Ravi

11
"this" และ getContext () ทั้งคู่เหมือนกัน
KCRaju

43
thisและgetContext()ไม่เหมือนกันเสมอเช่นในคลาสกิจกรรมคุณสามารถใช้thisเพราะActivityสืบทอดมาContextแต่เมธอดgetContext()ไม่ได้อยู่ในActivityคลาส @mikedroid @KCRaju
nandan

92

คำตอบส่วนใหญ่ครอบคลุมอยู่แล้วgetContext()และgetApplicationContext()แต่getBaseContext ()ไม่ค่อยได้อธิบาย

วิธีการที่มีความเกี่ยวข้องเฉพาะเมื่อคุณมีgetBaseContext() ContextWrapperAndroid จัดเตรียมContextWrapperคลาสที่สร้างขึ้นContextโดยใช้:

ContextWrapper wrapper = new ContextWrapper(context);

ประโยชน์ของการใช้ a ContextWrapperคือให้คุณ“ แก้ไขพฤติกรรมโดยไม่เปลี่ยนบริบทเดิม” ตัวอย่างเช่นหากคุณมีกิจกรรมที่เรียกว่าmyActivityสามารถสร้างViewธีมที่แตกต่างจากmyActivity:

ContextWrapper customTheme = new ContextWrapper(myActivity) {
  @Override
  public Resources.Theme getTheme() { 
    return someTheme;
  }
}
View myView = new MyView(customTheme);

ContextWrapperมีประสิทธิภาพจริงๆเพราะมันช่วยให้คุณสามารถแทนที่การทำงานมากที่สุดให้โดยContextรวมทั้งรหัสการเข้าถึงทรัพยากร (เช่นopenFileInput(), getString()) โต้ตอบกับส่วนประกอบอื่น ๆ (เช่นsendBroadcast(), registerReceiver()) สิทธิ์ร้องขอ (เช่นcheckCallingOrSelfPermission()) และสถานที่การแก้ไขระบบไฟล์ (เช่นgetFilesDir())ContextWrapperมีประโยชน์มากในการแก้ปัญหาเฉพาะอุปกรณ์ / รุ่นหรือใช้การปรับแต่งแบบครั้งเดียวกับส่วนประกอบเช่น Views ที่ต้องการบริบท

เมธอดgetBaseContext ()สามารถใช้เพื่อเข้าถึงบริบท“ พื้นฐาน” ที่ContextWrapperล้อมรอบ คุณอาจจำเป็นต้องเข้าถึง“ฐาน” บริบทถ้าคุณจำเป็นต้องยกตัวอย่างเช่นการตรวจสอบไม่ว่าจะเป็นService, ActivityหรือApplication:

public class CustomToast {
  public void makeText(Context context, int resId, int duration) {
    while (context instanceof ContextWrapper) {
      context = context.baseContext();
    }
    if (context instanceof Service)) {
      throw new RuntimeException("Cannot call this from a service");
    }
    ...
  }
}

หรือถ้าคุณต้องการเรียกใช้เมธอด“ untrapped”:

class MyCustomWrapper extends ContextWrapper {
  @Override
  public Drawable getWallpaper() {
    if (BuildInfo.DEBUG) {
      return mDebugBackground;
    } else {
      return getBaseContext().getWallpaper();
    }
  }
}

17
ฉันจะบอกว่านี่เป็นคำตอบที่สำคัญที่สุดหลังจากคำตอบที่ได้รับการยอมรับ
0leg

4
ฉันจะบอกว่าการดำรงอยู่ของContextWrapperเป็นหนึ่งในการตัดสินใจที่เลวร้ายที่สุดที่เคยทำโดยนักพัฒนาของกรอบ Android เมื่อพวกเขาตระหนักว่าพวกเขาสร้างทั้งครอบครัวของวัตถุของพระเจ้าแทนที่จะทำสิ่งที่ถูกต้องและเปลี่ยนรหัสไปสู่ความรับผิดชอบเดียวพวกเขาก็เพิ่มการแฮ็กที่น่าเกลียดที่อนุญาตให้เปลี่ยนพฤติกรรมบริบทโดยทำให้ต้นไม้ที่สืบทอดมีความลึก วิศวกรรมซอฟต์แวร์ไม่ดีเท่าที่ควร สำหรับเราพัฒนา IMHO ไม่มีใครเลยที่ควรใช้หรือgetBaseContext() ContextWrapperถ้าคุณทำ - มันเป็น "กลิ่นรหัส" ขนาดใหญ่
Vasiliy

ฉันต้องการที่จะเห็นCustomToastรหัสที่สมบูรณ์ THANKS:
Alston

39

getApplicationContext () - ส่งคืนบริบทสำหรับกิจกรรมทั้งหมดที่รันในแอปพลิเคชัน

getBaseContext () - หากคุณต้องการเข้าถึงบริบทจากบริบทอื่นภายในแอปพลิเคชันคุณสามารถเข้าถึงได้

getContext () - คืนค่ามุมมองบริบทเฉพาะกิจกรรมที่ดำเนินอยู่ปัจจุบัน


1
กรุณารวมตัวอักษร A และ B เข้ากับการกำหนดบริบทของคุณด้วยบริบทมันไม่ชัดเจนในคำตอบใด ๆ ที่เข้าถึงบริบท
หวังว่าช่วยได้

29

คำถาม "สิ่งที่บริบทคือ" เป็นหนึ่งในคำถามที่ยากที่สุดในจักรวาล Android

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

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

โพสต์บล็อกนี้พยายามสรุปการContextบังคับใช้คลาสในสถานการณ์ต่างๆ

ให้ฉันคัดลอกตารางหลักจากโพสต์นั้นเพื่อความสมบูรณ์:

+----------------------------+-------------+----------+---------+-----------------+-------------------+
|                            | Application | Activity | Service | ContentProvider | BroadcastReceiver |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
| Show a Dialog              | NO          | YES      | NO      | NO              | NO                |
| Start an Activity          | NO¹         | YES      | NO¹     | NO¹             | NO¹               |
| Layout Inflation           | NO²         | YES      | NO²     | NO²             | NO²               |
| Start a Service            | YES         | YES      | YES     | YES             | YES               |
| Bind to a Service          | YES         | YES      | YES     | YES             | NO                |
| Send a Broadcast           | YES         | YES      | YES     | YES             | YES               |
| Register BroadcastReceiver | YES         | YES      | YES     | YES             | NO³               |
| Load Resource Values       | YES         | YES      | YES     | YES             | YES               |
+----------------------------+-------------+----------+---------+-----------------+-------------------+
  1. แอปพลิเคชันสามารถเริ่มกิจกรรมได้จากที่นี่ แต่ต้องการให้สร้างงานใหม่ สิ่งนี้อาจเหมาะกับกรณีการใช้งานเฉพาะ แต่สามารถสร้างพฤติกรรมการสแต็กกลับที่ไม่ได้มาตรฐานในแอปพลิเคชันของคุณและโดยทั่วไปจะไม่แนะนำหรือถือว่าเป็นแนวปฏิบัติที่ดี
  2. สิ่งนี้เป็นสิ่งถูกกฎหมาย แต่เงินเฟ้อจะทำกับธีมเริ่มต้นสำหรับระบบที่คุณใช้งานไม่ใช่สิ่งที่กำหนดไว้ในแอปพลิเคชันของคุณ
  3. อนุญาตถ้าผู้รับเป็นโมฆะซึ่งใช้สำหรับรับค่าปัจจุบันของการออกอากาศแบบติดหนึบบน Android 4.2 ขึ้นไป

ภาพหน้าจอ


โพสต์บล็อกที่ยอดเยี่ยมที่คุณเชื่อมโยง!
lejonl

28

Contextให้ข้อมูลเกี่ยวกับActvityหรือApplicationส่วนประกอบที่สร้างขึ้นใหม่

Contextควรจัดให้มีความเกี่ยวข้องกับส่วนประกอบที่สร้างขึ้นใหม่ (ไม่ว่าจะเป็นบริบทแอปพลิเคชันหรือบริบทของกิจกรรม)

เนื่องจากActivityเป็นคลาสย่อยของContextหนึ่งสามารถใช้thisเพื่อรับบริบทของกิจกรรมนั้น


คำอธิบายของคุณเกี่ยวกับ baseContext อยู่ที่ไหน
IgorGanapolsky


0

getApplicationContext ()

สิ่งนี้ใช้สำหรับระดับแอปพลิเคชันและอ้างอิงถึงกิจกรรมทั้งหมด

getContext () และ getBaseContext ()

มันอาจจะเหมือนกันมากที่สุด. เหล่านี้จะกล่าวถึงเฉพาะกิจกรรมปัจจุบันที่ยังมีชีวิตอยู่

นี้

อ้างอิงคลาสวัตถุปัจจุบันเสมอ


0

A Contextคือ:

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