ความแตกต่างระหว่างคืออะไร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()
ContextWrapper
Android จัดเตรียม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
เราควรใช้มันจะซับซ้อนมากเพราะยกเว้นว่าเป็นวัตถุของพระเจ้าต้นไม้ลำดับชั้นของContext
subclasses ละเมิดหลักการแทน 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
คือ: