@hide หมายถึงอะไรในซอร์สโค้ด Android


120

สำหรับActivityซอร์สโค้ดบรรทัด 3898 (ใกล้กับด้านล่าง):

/**
 * @hide
 */
public final boolean isResumed() {
    return mResumed;
}

อะไร@hideหมายถึง?

ฉันพบว่าpublic class ChildActivity extends Activity { ... }ไม่สามารถใช้ / ดูActivity.isResumed()ได้ เป็นเรื่องปกติหรือไม่? ฉันจะเข้าถึงได้อย่างไร?

คำตอบ:


182

Android มี API สองประเภทที่ไม่สามารถเข้าถึงได้ผ่าน SDK

com.android.internalคนแรกที่ตั้งอยู่ในแพคเกจ ประเภทที่สองคือ API คอลเลกชันของการเรียนและวิธีการที่ถูกทำเครื่องหมายด้วยแอตทริบิวต์ @hide Javadoc

เริ่มจาก Android 9 (API ระดับ 28) Google แนะนำข้อ จำกัด ใหม่เกี่ยวกับการใช้อินเทอร์เฟซที่ไม่ใช่ SDKไม่ว่าจะโดยตรงผ่านการสะท้อนกลับหรือผ่าน JNI ข้อ จำกัด เหล่านี้จะนำไปใช้เมื่อใดก็ตามที่แอปอ้างถึงอินเทอร์เฟซที่ไม่ใช่ SDK หรือพยายามที่จะจัดการโดยใช้การสะท้อนกลับหรือ JNI

แต่ก่อน API ระดับ 28 ยังสามารถเข้าถึงเมธอดที่ซ่อนอยู่ผ่านการสะท้อนของ Java @hideแอตทริบิวต์เป็นเพียงส่วนหนึ่งของ Javadoc (droiddoc ยัง) ดังนั้น@hideเพียงแค่หมายถึงวิธีการ / ระดับ / สาขาได้รับการยกเว้นจากเอกสารของ API

ตัวอย่างเช่นcheckUidPermission()วิธีการActivityManager.javaใช้@hide:

/** @hide */
public static int checkUidPermission(String permission, int uid) {
    try {
        return AppGlobals.getPackageManager()
                .checkUidPermission(permission, uid);
    } catch (RemoteException e) {
        // Should never happen, but if it does... deny!
        Slog.e(TAG, "PackageManager is dead?!?", e);
    }
    return PackageManager.PERMISSION_DENIED;
}

อย่างไรก็ตามเราสามารถเรียกมันโดยการไตร่ตรอง:

Class c;
c = Class.forName("android.app.ActivityManager");
Method m = c.getMethod("checkUidPermission", new Class[] {String.class, int.class});
Object o = m.invoke(null, new Object[]{"android.permission.READ_CONTACTS", 10010});

1
สวัสดี @StarPinkER ฉันสามารถให้สิทธิ์ "android.permission.CHANGE_COMPONENT_ENABLED_STATE" โดยใช้ API ที่ซ่อนอยู่หรือภายในหรือโดยการอ้างอิงได้หรือไม่
Hardik

1
ตรวจสอบคำตอบนี้ก่อน การอนุญาตนี้เป็นการอนุญาตลายเซ็น / ระบบ ในกรณีส่วนใหญ่คุณจะไม่ได้รับอนุญาตนี้เว้นแต่จะเป็นแอปพลิเคชันระบบ นั่นหมายความว่าคุณต้องแก้ไขซอร์สของ Android เพื่อยอมรับแอปของคุณหรือทำให้แอปของคุณเป็นแอประบบและลงนาม อย่างไรก็ตามคุณจะไม่สามารถทำได้เว้นแต่คุณจะสร้างระบบ Android ของคุณเอง การสะท้อนสามารถจัดการกับ "การซ่อน" ได้ แต่ไม่สามารถเปลี่ยนตรรกะของระบบความปลอดภัยของ Android ได้ คุณสามารถจินตนาการได้ว่าเราจะโจมตีอุปกรณ์ Android ได้อย่างไรหากเราสามารถทำได้ @Hardik
StarPinkER

2
ขอบคุณสำหรับคำตอบ แต่ฉันคิดว่ามีปัญหาสองประการในคำตอบโปรดแก้ไขฉันถ้าฉันผิด ฉันได้รับข้อผิดพลาด classnotfound หากพยายามค้นหาโดย "ActivityManager" แทน "android.app.ActivityManager" และ "m.invoke (c" น่าจะเป็น "m.invoke (null" สำหรับวิธีการคงที่และ "m. เรียกใช้ (o, "โดยที่ o เป็นอ็อบเจ็กต์ประเภท c สำหรับวิธีการแบบไดนามิกขออภัยไวยากรณ์ภาษาโปแลนด์ของฉัน :)
lindenrovio

3
หมายเหตุเกี่ยวกับการไตร่ตรอง: เนื่องจากวิธีการ / ฟิลด์เหล่านั้นไม่ได้เป็นส่วนหนึ่งของ SDK อย่างเป็นทางการจึงไม่มีการรับประกันว่าจะมีอยู่ในการแก้ไข Android ในอนาคต
sstn

2
หากคำอธิบายประกอบเพียงลบเมธอดออกจากเอกสารทำไมฉันจึงยังใช้มันในโค้ดไม่ได้
Javier Delgado

25
  1. @hideใช้สำหรับสิ่งที่ต้องการให้มองเห็นได้ด้วยเหตุผลหลายประการ แต่ไม่ได้เป็นส่วนหนึ่งของ API ที่เผยแพร่ ซึ่งจะไม่รวมอยู่ในเอกสารประกอบเมื่อแยก API จากต้นทางโดยอัตโนมัติ

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

  3. คุณไม่ควรใช้เลยเนื่องจากไม่ใช่ส่วนหนึ่งของ API และนักพัฒนาสามารถลบออกได้ทุกเมื่อที่ต้องการ แม้ว่าพวกเขาจะอยู่ในสิทธิ์ของพวกเขาพวกเขาเอนเอียงไปทางซาดิสต์ที่จะแทนที่ด้วยฟังก์ชันที่ปิดกั้นอุปกรณ์ที่มันทำงานอยู่ (แม้ว่าอาจจะไม่ถูกต้องตามหลักกฎหมายก็ตาม)


โอ้ใช่ ... finalแน่นอนว่าฉันไม่สามารถลบล้างได้ ขออภัยนั่นคือความผิดพลาดของฉัน: x
midnite

คุณหมายความว่ามันอยู่publicในทุกชั้นเรียนระหว่างขั้นตอนการพัฒนา แต่มันทำเหมือนprivateหรือ/*package*/กับผู้ใช้อย่างเรา?
midnite

อืม ... นั่นเป็นเพียงความคิดเห็น ฉันเข้าใจความหมายของมัน แต่จะบังคับใช้พฤติกรรมนี้ในระดับรหัสอย่างไรและที่ไหน?
midnite

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

1
@midnite Eclipse มีคอมไพเลอร์ Java ของตัวเองซึ่งไม่ต้องสงสัยเลยว่ารวมเข้ากับสิ่งที่เป็น intellisense ฉันขอแนะนำว่าถ้าคุณรวบรวมสิ่งนี้ด้วย Java SDK มันจะคอมไพล์ได้ดี ไม่ใช่ว่าฉันแนะนำสิ่งนี้แน่นอนดูจุดที่ 3
paxdiablo

4

@hideคำอธิบายประกอบหมายความว่าอินเตอร์เฟซนี้ไม่ได้เป็นส่วนหนึ่งของประชาชน API และไม่ควรนำมาใช้ในรหัสของคุณ วิธีนี้ใช้สำหรับการใช้งานภายในของ AOSP เท่านั้น

Google ได้เริ่มจำกัด การใช้งานอินเทอร์เฟซที่ไม่ใช่ sdkแล้ว ซึ่งรวมถึงอินเทอร์เฟซที่มีเครื่องหมาย@hide

วิธีการแบ่งออกเป็นสี่รายการ:

  • รายการที่อนุญาต: SDK
  • light-greylist: วิธีการ / ฟิลด์ที่ไม่ใช่ SDK ที่ยังสามารถเข้าถึงได้
  • เข้มอนุโลม:
    • สำหรับแอปที่ SDK เป้าหมายต่ำกว่า API ระดับ 28: อนุญาตให้ใช้อินเทอร์เฟซ Dark Greylist แต่ละครั้งได้
    • สำหรับแอปที่มี SDK เป้าหมายคือ API ระดับ 28 ขึ้นไป: ลักษณะการทำงานเหมือนกับบัญชีดำ
  • บัญชีดำ: ถูก จำกัด โดยไม่คำนึงถึง SDK เป้าหมาย แพลตฟอร์มจะทำงานราวกับว่าไม่มีอินเทอร์เฟซอยู่ ตัวอย่างเช่นจะโยน NoSuchMethodError / NoSuchFieldException เมื่อใดก็ตามที่แอปพยายามใช้งานและจะไม่รวมไว้เมื่อแอปต้องการทราบรายการฟิลด์ / วิธีการของคลาสเฉพาะ

ดูรายการได้ที่นี่: https://android.googlesource.com/platform/prebuilts/runtime/+/master/appcompat

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