ความแตกต่างระหว่างคืออะไรgetContext(), getApplicationContext(), getBaseContext()และ " this"?
แม้ว่านี่เป็นคำถามง่าย ๆ ที่ฉันไม่สามารถเข้าใจความแตกต่างพื้นฐานระหว่างพวกเขา โปรดยกตัวอย่างง่ายๆถ้าเป็นไปได้
ความแตกต่างระหว่างคืออะไรgetContext(), getApplicationContext(), getBaseContext()และ " this"?
แม้ว่านี่เป็นคำถามง่าย ๆ ที่ฉันไม่สามารถเข้าใจความแตกต่างพื้นฐานระหว่างพวกเขา โปรดยกตัวอย่างง่ายๆถ้าเป็นไปได้
คำตอบ:
View.getContext(): ส่งคืนบริบทที่มุมมองกำลังทำงานอยู่โดยปกติแล้วเป็นกิจกรรมที่ใช้งานอยู่ในปัจจุบัน
Activity.getApplicationContext(): ส่งคืนบริบทสำหรับแอปพลิเคชันทั้งหมด (กระบวนการทั้งหมดที่กิจกรรมกำลังทำงานอยู่ภายใน) ใช้สิ่งนี้แทนบริบทของกิจกรรมปัจจุบันหากคุณต้องการบริบทที่เชื่อมโยงกับวงจรชีวิตของแอปพลิเคชันทั้งหมดไม่ใช่เฉพาะกับกิจกรรมปัจจุบัน
ContextWrapper.getBaseContext(): หากคุณต้องการเข้าถึงบริบทจากภายในบริบทอื่นคุณใช้ ContextWrapper บริบทที่อ้างถึงจากภายในซึ่งเข้าถึง ContextWrapper ผ่าน getBaseContext ()
thisและgetContext()ไม่เหมือนกันเสมอเช่นในคลาสกิจกรรมคุณสามารถใช้thisเพราะActivityสืบทอดมาContextแต่เมธอดgetContext()ไม่ได้อยู่ในActivityคลาส @mikedroid @KCRaju
                    คำตอบส่วนใหญ่ครอบคลุมอยู่แล้ว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();
    }
  }
}ContextWrapperเป็นหนึ่งในการตัดสินใจที่เลวร้ายที่สุดที่เคยทำโดยนักพัฒนาของกรอบ Android เมื่อพวกเขาตระหนักว่าพวกเขาสร้างทั้งครอบครัวของวัตถุของพระเจ้าแทนที่จะทำสิ่งที่ถูกต้องและเปลี่ยนรหัสไปสู่ความรับผิดชอบเดียวพวกเขาก็เพิ่มการแฮ็กที่น่าเกลียดที่อนุญาตให้เปลี่ยนพฤติกรรมบริบทโดยทำให้ต้นไม้ที่สืบทอดมีความลึก วิศวกรรมซอฟต์แวร์ไม่ดีเท่าที่ควร สำหรับเราพัฒนา IMHO ไม่มีใครเลยที่ควรใช้หรือgetBaseContext() ContextWrapperถ้าคุณทำ - มันเป็น "กลิ่นรหัส" ขนาดใหญ่
                    CustomToastรหัสที่สมบูรณ์ THANKS:
                    getApplicationContext () - ส่งคืนบริบทสำหรับกิจกรรมทั้งหมดที่รันในแอปพลิเคชัน
getBaseContext () - หากคุณต้องการเข้าถึงบริบทจากบริบทอื่นภายในแอปพลิเคชันคุณสามารถเข้าถึงได้
getContext () - คืนค่ามุมมองบริบทเฉพาะกิจกรรมที่ดำเนินอยู่ปัจจุบัน
คำถาม "สิ่งที่บริบทคือ" เป็นหนึ่งในคำถามที่ยากที่สุดในจักรวาล 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 | +----------------------------+-------------+----------+---------+-----------------+-------------------+
- แอปพลิเคชันสามารถเริ่มกิจกรรมได้จากที่นี่ แต่ต้องการให้สร้างงานใหม่ สิ่งนี้อาจเหมาะกับกรณีการใช้งานเฉพาะ แต่สามารถสร้างพฤติกรรมการสแต็กกลับที่ไม่ได้มาตรฐานในแอปพลิเคชันของคุณและโดยทั่วไปจะไม่แนะนำหรือถือว่าเป็นแนวปฏิบัติที่ดี
- สิ่งนี้เป็นสิ่งถูกกฎหมาย แต่เงินเฟ้อจะทำกับธีมเริ่มต้นสำหรับระบบที่คุณใช้งานไม่ใช่สิ่งที่กำหนดไว้ในแอปพลิเคชันของคุณ
- อนุญาตถ้าผู้รับเป็นโมฆะซึ่งใช้สำหรับรับค่าปัจจุบันของการออกอากาศแบบติดหนึบบน Android 4.2 ขึ้นไป
Contextให้ข้อมูลเกี่ยวกับActvityหรือApplicationส่วนประกอบที่สร้างขึ้นใหม่
Contextควรจัดให้มีความเกี่ยวข้องกับส่วนประกอบที่สร้างขึ้นใหม่ (ไม่ว่าจะเป็นบริบทแอปพลิเคชันหรือบริบทของกิจกรรม)
เนื่องจากActivityเป็นคลาสย่อยของContextหนึ่งสามารถใช้thisเพื่อรับบริบทของกิจกรรมนั้น
getApplicationContext ()
สิ่งนี้ใช้สำหรับระดับแอปพลิเคชันและอ้างอิงถึงกิจกรรมทั้งหมด
getContext () และ getBaseContext ()
มันอาจจะเหมือนกันมากที่สุด. เหล่านี้จะกล่าวถึงเฉพาะกิจกรรมปัจจุบันที่ยังมีชีวิตอยู่
นี้
อ้างอิงคลาสวัตถุปัจจุบันเสมอ
A Contextคือ: