ปรับปรุงการตรวจสอบโค้ดด้วยหมายเหตุ

การใช้เครื่องมือตรวจสอบโค้ด เช่น lint จะช่วยให้การค้นหา ปัญหาและปรับปรุงโค้ดของคุณ แต่เครื่องมือตรวจสอบสามารถอนุมานได้มากเท่านั้น รหัสทรัพยากร Android เช่น ใช้ int เพื่อระบุสตริง กราฟิก สี และทรัพยากรประเภทอื่นๆ ดังนั้นเครื่องมือตรวจสอบจะไม่สามารถบอกได้เมื่อคุณระบุทรัพยากรสตริงที่ควรจะมี ระบุสีแล้ว กรณีนี้หมายความว่าแอปอาจแสดงผลไม่ถูกต้องหรือไม่ทำงานเลย แม้ว่าคุณจะใช้การตรวจสอบโค้ดก็ตาม

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

Android สนับสนุนคำอธิบายประกอบที่หลากหลายผ่าน ไลบรารีคำอธิบายประกอบของ Jetpack คุณสามารถเข้าถึงไลบรารีผ่านทาง androidx.annotation ใหม่

หมายเหตุ: หากโมดูลมีทรัพยากร Dependency ในโปรเซสเซอร์คำอธิบายประกอบ คุณต้องใช้การกำหนดค่าทรัพยากร Dependency kapt หรือ ksp สำหรับ Kotlin หรือการกำหนดค่าทรัพยากร Dependency annotationProcessor สำหรับ Java เพื่อเพิ่ม การพึ่งพา

เพิ่มคำอธิบายประกอบลงในโปรเจ็กต์

หากต้องการเปิดใช้คำอธิบายประกอบในโปรเจ็กต์ ให้เพิ่ม androidx.annotation:annotation ที่ขึ้นอยู่กับไลบรารีหรือแอปของคุณ จะมีการทำเครื่องหมายคำอธิบายประกอบทั้งหมดเมื่อคุณเรียกใช้โค้ด การตรวจสอบหรืองานlint

เพิ่มการพึ่งพาไลบรารีคำอธิบายประกอบของ Jetpack

ไลบรารีคำอธิบายประกอบของ Jetpack เผยแพร่เมื่อ ที่เก็บ Maven ของ Google หากต้องการเพิ่มไลบรารี Jetpack Anotations ลงในโปรเจ็กต์ ให้ใส่รายการต่อไปนี้ ในบล็อก dependencies ของ build.gradle หรือ build.gradle.kts ไฟล์:

Kotlin

dependencies {
    implementation("androidx.annotation:annotation:1.8.1")
}

ดึงดูด

dependencies {
    implementation 'androidx.annotation:annotation:1.8.1'
}
จากนั้นในแถบเครื่องมือหรือการแจ้งเตือนการซิงค์ที่ปรากฏขึ้น ให้คลิกซิงค์เลย

หากคุณใช้คำอธิบายประกอบในโมดูลไลบรารีของคุณเอง คำอธิบายประกอบจะรวมไว้เป็นส่วนหนึ่งของ อาร์ติแฟกต์ Android Archive (AAR) ในรูปแบบ XML ในไฟล์ annotations.zip การเพิ่ม ทรัพยากร Dependency ของ androidx.annotation ไม่เรียกใช้ทรัพยากร Dependency สำหรับผู้ใช้ดาวน์สตรีม ของไลบรารีก็ได้

หมายเหตุ: หากคุณใช้ไลบรารี Jetpack อื่นๆ คุณอาจไม่จำเป็นต้องเพิ่มการอ้างอิง androidx.annotation เพราะคนอื่นๆ ไลบรารี Jetpack อาศัยไลบรารีคำอธิบายประกอบซึ่งคุณอาจมีสิทธิ์เข้าถึงอยู่แล้ว คำอธิบายประกอบ

ดูรายการคำอธิบายประกอบทั้งหมดที่รวมอยู่ในที่เก็บ Jetpack ได้ที่ ไลบรารีคำอธิบายประกอบของ Jetpack อ้างอิงหรือใช้ฟีเจอร์การเติมข้อความอัตโนมัติเพื่อแสดงตัวเลือกที่พร้อมใช้งานสำหรับ คำสั่ง import androidx.annotation.

เรียกใช้การตรวจสอบโค้ด

เริ่มการตรวจสอบโค้ดจาก Android Studio ซึ่งรวมถึงการตรวจสอบคำอธิบายประกอบและ การตรวจสอบ Lint อัตโนมัติ เลือกวิเคราะห์ > ตรวจสอบโค้ดจาก เมนู Android Studio แสดงข้อความที่ขัดแย้งกันเพื่อแจ้งปัญหาที่อาจเกิดขึ้นซึ่งโค้ดของคุณ ขัดแย้งกับคำอธิบายประกอบ และเพื่อแนะนำวิธีแก้ปัญหาที่เป็นไปได้

คุณยังสามารถบังคับใช้คำอธิบายประกอบโดยการเรียกใช้ lint โดยใช้บรรทัดคำสั่ง แม้ว่าวิธีนี้อาจมีประโยชน์สำหรับการแจ้งปัญหา กับเซิร์ฟเวอร์การผสานรวมอย่างต่อเนื่อง งานของ lint จะไม่บังคับใช้ Null คำอธิบายประกอบ (อธิบายไว้ในส่วนต่อไปนี้) โดยใช้ Android Studio เท่านั้น สำหรับข้อมูลเพิ่มเติม ข้อมูลเกี่ยวกับการเปิดใช้และเรียกใช้ Lint จากการตรวจสอบ โปรดดูการปรับปรุงโค้ดของคุณด้วย Lint การตรวจสอบ

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

คำอธิบายประกอบ Null

คำอธิบายประกอบ Null อาจมีประโยชน์ในโค้ด Java เพื่อบังคับใช้ว่าค่าเป็น Null หรือไม่ มีประโยชน์น้อยกว่าในโค้ด Kotlin เนื่องจาก Kotlin สร้างกฎความสามารถในการเว้นว่างซึ่งบังคับใช้ที่ เวลาคอมไพล์

เพิ่ม @Nullable และ คำอธิบายประกอบ @NonNull รายการ เพื่อตรวจสอบค่า Null ของตัวแปร พารามิเตอร์ หรือค่าผลลัพธ์ที่กำหนด @Nullable จะระบุตัวแปร พารามิเตอร์ หรือค่าที่เป็นค่าว่าง @NonNull บ่งบอกถึงตัวแปร พารามิเตอร์ หรือค่าที่ส่งคืนต้องไม่เป็นค่าว่าง

เช่น หากมีการส่งตัวแปรภายในที่มีค่า Null เป็นพารามิเตอร์ไปยังเมธอด ที่มีคำอธิบายประกอบ @NonNull แนบอยู่กับพารามิเตอร์ดังกล่าว การสร้างโค้ดจะสร้าง คำเตือนที่ระบุข้อขัดแย้งที่ไม่เป็นค่าว่าง นอกจากนี้ มีความพยายามอ้างอิงผลลัพธ์ของ เมธอดที่ทำเครื่องหมายด้วย @Nullable โดยไม่ได้ตรวจสอบก่อนว่าผลลัพธ์เป็น null ที่สร้างหรือไม่ คำเตือนค่า Null ใช้ @Nullable กับค่าผลลัพธ์ของเมธอดเท่านั้น หากทุกการใช้เมธอดต้องได้รับการตรวจสอบอย่างชัดแจ้ง

ตัวอย่างต่อไปนี้แสดงการใช้งานจริงที่เป็นโมฆะ โค้ดตัวอย่าง Kotlin ไม่ใช้ประโยชน์จาก คำอธิบายประกอบ @NonNull เพราะระบบจะเพิ่มลงในไบต์โค้ดที่สร้างขึ้นโดยอัตโนมัติ เมื่อมีการระบุประเภทที่ไม่เป็นค่าว่าง ตัวอย่าง Java ใช้ประโยชน์จากคำอธิบายประกอบ @NonNull ในพารามิเตอร์ context และ attrs เพื่อตรวจสอบว่าค่าพารามิเตอร์ที่ส่งผ่าน ไม่เป็นค่าว่าง นอกจากนี้ยังตรวจสอบว่าเมธอด onCreateView() เองไม่แสดงผล Null:

Kotlin

...
    /** Annotation not used because of the safe-call operator(?)**/
    override fun onCreateView(
            name: String?,
            context: Context,
            attrs: AttributeSet
    ): View? {
        ...
    }
...

Java

import androidx.annotation.NonNull;
...
    /** Add support for inflating the <fragment> tag. **/
    @NonNull
    @Override
    public View onCreateView(String name, @NonNull Context context,
      @NonNull AttributeSet attrs) {
      ...
      }
...

การวิเคราะห์ความสามารถในการเว้นว่าง

Android Studio รองรับการเรียกใช้การวิเคราะห์ค่า Null เพื่ออนุมานโดยอัตโนมัติ และแทรกคำอธิบายประกอบ Nullness ในโค้ดของคุณ การสแกนการวิเคราะห์ความสามารถในการเว้นว่าง สัญญาตลอดทั้งลำดับชั้นของเมธอดในโค้ดของคุณเพื่อตรวจหาสิ่งต่อไปนี้

  • วิธีการโทรที่ส่งคืนค่า Null ได้
  • วิธีการที่ไม่ควรแสดงผลเป็น Null
  • เช่น ช่อง ตัวแปรภายใน และพารามิเตอร์ที่อาจ ค่าว่าง
  • เช่น ช่อง ตัวแปรในเครื่อง และพารามิเตอร์ที่ไม่สามารถ เก็บค่า Null

จากนั้นการวิเคราะห์จะแทรกคำอธิบายประกอบ Null ที่เหมาะสมลงใน ตำแหน่งที่ตรวจพบ

หากต้องการเรียกใช้การวิเคราะห์ความสามารถในการเว้นว่างใน Android Studio ให้เลือกวิเคราะห์ > อนุมาน Nullity Android Studio จะแทรกคำอธิบายประกอบของ Android @Nullable และ @NonNull ใน ตำแหน่งที่ตรวจพบในโค้ดของคุณ หลังจากทำการวิเคราะห์ Null แล้ว ควรตรวจสอบ ที่แทรกคำอธิบายประกอบ

หมายเหตุ: เมื่อเพิ่มคำอธิบายประกอบที่ไม่มีข้อมูล การเติมข้อความอัตโนมัติอาจ แนะนำ IntelliJ @Nullable และ คำอธิบายประกอบ @NotNull แทนคำอธิบายประกอบ Android Null และอาจนำเข้าไลบรารีที่เกี่ยวข้องโดยอัตโนมัติ อย่างไรก็ตาม Android Studio โปรแกรมตรวจสอบ Lint จะค้นหาเฉพาะคำอธิบายประกอบ Android Null เท่านั้น เมื่อทำการยืนยัน ให้ยืนยันว่าโครงการของคุณใช้คำอธิบายประกอบ Android Null เพื่อให้ โปรแกรมตรวจสอบ Lint สามารถแจ้งให้คุณทราบได้อย่างถูกต้องในระหว่างการตรวจสอบโค้ด

คำอธิบายประกอบแหล่งข้อมูล

การตรวจสอบประเภททรัพยากรนั้นอาจมีประโยชน์เนื่องจากการอ้างอิงทรัพยากรของ Android เช่น ทรัพยากรที่วาดได้และสตริง จะส่งค่าเป็นจำนวนเต็ม

โค้ดที่คาดหวังให้พารามิเตอร์อ้างอิงประเภททรัพยากรที่เฉพาะเจาะจง เช่น String สามารถส่งผ่านไปยังประเภทการอ้างอิง int ที่คาดไว้ แต่แท้จริงแล้วเป็นการอ้างอิง ประเภททรัพยากร เช่น ทรัพยากร R.string

เช่น เพิ่มคำอธิบายประกอบ @StringRes ให้กับ ตรวจสอบว่าพารามิเตอร์ทรัพยากรมีการอ้างอิง R.string หรือไม่ ตามที่แสดงไว้ที่นี่

Kotlin

abstract fun setTitle(@StringRes resId: Int)

Java

public abstract void setTitle(@StringRes int resId)

ระหว่างการตรวจสอบโค้ด คำอธิบายประกอบจะสร้างคำเตือนหากการอ้างอิง R.string ไม่ได้ส่งผ่านในพารามิเตอร์

คำอธิบายประกอบสำหรับทรัพยากรประเภทอื่นๆ เช่น @DrawableRes, @DimenRes, @ColorRes และ @InterpolatorRes สามารถเป็นได้ โดยใช้รูปแบบคำอธิบายประกอบเดียวกันและเรียกใช้ระหว่างการตรวจสอบโค้ด

หากพารามิเตอร์ของคุณ รองรับทรัพยากรหลายประเภท พารามิเตอร์ ใช้ @AnyRes เพื่อระบุว่าพารามิเตอร์ที่มีคำอธิบายประกอบอาจเป็นทรัพยากร R ประเภทใดก็ได้

แม้ว่าคุณจะสามารถใช้ @ColorRes เพื่อระบุว่า ควรเป็นแหล่งข้อมูลสี จำนวนเต็มของสี (ใน RRGGBB หรือ AARRGGBB) ไม่รับรู้เป็นทรัพยากรสี แต่ให้ใช้คำอธิบายประกอบ @ColorInt แทนเพื่อ บอกว่าพารามิเตอร์ต้องเป็นจำนวนเต็มของสี เครื่องมือสร้างจะแจ้งว่าโค้ดไม่ถูกต้องซึ่ง ส่งผ่านรหัสทรัพยากรสี เช่น android.R.color.black แทนที่จะเป็นจำนวนเต็มสี ไปจนถึงเมธอดที่มีคำอธิบายประกอบ

คำอธิบายประกอบชุดข้อความ

คำอธิบายประกอบชุดข้อความจะตรวจสอบว่าเมธอดมีการเรียกจากประเภท thread ชุดข้อความต่อไปนี้ คำอธิบายประกอบที่รองรับมีดังนี้

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

หากวิธีการทั้งหมดในชั้นเรียนมีข้อกำหนดการแยกชุดข้อความเดียวกัน คุณจะเพิ่มชุดข้อความเดียวได้ ลงในคลาสเพื่อยืนยันว่าเมธอดทั้งหมดในชั้นเรียนนั้นถูกเรียกจากประเภท ชุดข้อความ

การใช้งานทั่วไปของคำอธิบายประกอบเทรดคือการตรวจสอบว่าเมธอดหรือคลาสที่มีคำอธิบายประกอบ ระบบจะเรียก @WorkerThread จากชุดข้อความเบื้องหลังที่เหมาะสมเท่านั้น

คำอธิบายประกอบที่จำกัดค่า

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

คำอธิบายประกอบ @IntRange จะตรวจสอบว่าจำนวนเต็มหรือพารามิเตอร์แบบยาว อยู่ภายในช่วงที่ระบุ ตัวอย่างต่อไปนี้ระบุว่า alpha ต้องมีค่าจำนวนเต็มตั้งแต่ 0 ถึง 255

Kotlin

fun setAlpha(@IntRange(from = 0, to = 255) alpha: Int) { ... }

Java

public void setAlpha(@IntRange(from=0,to=255) int alpha) { ... }

คำอธิบายประกอบ @FloatRange จะตรวจสอบว่าพารามิเตอร์แบบลอยหรือคู่ อยู่ในช่วงที่ระบุของค่าทศนิยม ตัวอย่างต่อไปนี้ระบุว่า พารามิเตอร์ alpha ต้องมีค่าทศนิยมตั้งแต่ 0.0 ถึง 1.0

Kotlin

fun setAlpha(@FloatRange(from = 0.0, to = 1.0) alpha: Float) {...}

Java

public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {...}

คำอธิบายประกอบ @Size จะตรวจสอบขนาดของคอลเล็กชันหรือ หรือความยาวของสตริง ใช้คำอธิบายประกอบ @Size เพื่อยืนยันได้ คุณภาพต่อไปนี้

  • ขนาดต่ำสุด เช่น @Size(min=2)
  • ขนาดสูงสุด เช่น @Size(max=2)
  • ขนาดที่แน่นอน เช่น @Size(2)
  • ตัวเลขที่ขนาดต้องเป็นผลคูณ เช่น @Size(multiple=2)

เช่น @Size(min=1) ตรวจสอบว่าคอลเล็กชันไม่ว่างเปล่าหรือไม่ และ @Size(3) จะตรวจสอบว่าอาร์เรย์มีค่า 3 ค่าเท่านั้น

ตัวอย่างต่อไปนี้ระบุว่า อาร์เรย์ location ต้องมีองค์ประกอบอย่างน้อย 1 รายการ

Kotlin

fun getLocation(button: View, @Size(min=1) location: IntArray) {
    button.getLocationOnScreen(location)
}

Java

void getLocation(View button, @Size(min=1) int[] location) {
    button.getLocationOnScreen(location);
}

หมายเหตุเกี่ยวกับสิทธิ์

ใช้ @RequiresPermission เพื่อตรวจสอบสิทธิ์ของผู้เรียกใช้เมธอด วิธีตรวจสอบสิทธิ์รายการเดียว จากรายการสิทธิ์ที่ถูกต้อง ให้ใช้แอตทริบิวต์ anyOf หากต้องการตรวจสอบชุดของ สิทธิ์ ให้ใช้แอตทริบิวต์ allOf ตัวอย่างต่อไปนี้อธิบาย setWallpaper() เพื่อระบุว่าผู้เรียกใช้เมธอดต้องมีเมธอด สิทธิ์permission.SET_WALLPAPERS:

Kotlin

@RequiresPermission(Manifest.permission.SET_WALLPAPER)
@Throws(IOException::class)
abstract fun setWallpaper(bitmap: Bitmap)

Java

@RequiresPermission(Manifest.permission.SET_WALLPAPER)
public abstract void setWallpaper(Bitmap bitmap) throws IOException;

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

Kotlin

@RequiresPermission(allOf = [
    Manifest.permission.READ_EXTERNAL_STORAGE,
    Manifest.permission.ACCESS_MEDIA_LOCATION
])
fun copyImageFile(dest: String, source: String) {
    ...
}

Java

@RequiresPermission(allOf = {
    Manifest.permission.READ_EXTERNAL_STORAGE,
    Manifest.permission.ACCESS_MEDIA_LOCATION})
public static final void copyImageFile(String dest, String source) {
    //...
}

สำหรับสิทธิ์เกี่ยวกับ Intent ให้วางข้อกำหนดสิทธิ์ในช่องสตริงที่กำหนด ชื่อการดำเนินการของ Intent:

Kotlin

@RequiresPermission(android.Manifest.permission.BLUETOOTH)
const val ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE"

Java

@RequiresPermission(android.Manifest.permission.BLUETOOTH)
public static final String ACTION_REQUEST_DISCOVERABLE =
            "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";

สำหรับสิทธิ์ของผู้ให้บริการเนื้อหาที่ต้องการสิทธิ์แยกต่างหากสำหรับการอ่านและเขียน เข้าถึงได้ ให้รวมข้อกำหนดสิทธิ์แต่ละข้อไว้ใน @RequiresPermission.Read หรือ @RequiresPermission.Write หมายเหตุ:

Kotlin

@RequiresPermission.Read(RequiresPermission(READ_HISTORY_BOOKMARKS))
@RequiresPermission.Write(RequiresPermission(WRITE_HISTORY_BOOKMARKS))
val BOOKMARKS_URI = Uri.parse("content://browser/bookmarks")

Java

@RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS))
@RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS))
public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");

สิทธิ์โดยอ้อม

เมื่อสิทธิ์ขึ้นอยู่กับค่าเฉพาะที่ระบุให้กับพารามิเตอร์ของเมธอด ให้ใช้ @RequiresPermission ในพารามิเตอร์เองโดยไม่แสดงรายการสิทธิ์ที่เฉพาะเจาะจง ตัวอย่างเช่น startActivity(Intent) วิธีนี้จะใช้สิทธิ์โดยอ้อมใน Intent ที่ส่งไปยังเมธอด

Kotlin

abstract fun startActivity(@RequiresPermission intent: Intent, bundle: Bundle?)

Java

public abstract void startActivity(@RequiresPermission Intent intent, @Nullable Bundle)

เมื่อคุณใช้สิทธิ์โดยอ้อม เครื่องมือสร้างจะวิเคราะห์โฟลว์ข้อมูลเพื่อตรวจสอบว่า อาร์กิวเมนต์ที่ส่งผ่านลงในเมธอดมีคำอธิบายประกอบ @RequiresPermission จากนั้น บังคับใช้คำอธิบายประกอบที่มีอยู่จากพารามิเตอร์ในเมธอดนั้นๆ ใน ตัวอย่าง startActivity(Intent) คำอธิบายประกอบในคลาส Intent ทำให้เกิดคำเตือน เกี่ยวกับการใช้ startActivity(Intent) ที่ไม่ถูกต้องเมื่อ Intent โดยไม่มี จะส่งไปยังเมธอด ดังแสดงในรูปที่ 1

รูปที่ 1 คำเตือนที่สร้างขึ้นจาก ในเมธอด startActivity(Intent)

เครื่องมือบิลด์จะสร้างคำเตือนใน startActivity(Intent) จากคำอธิบายประกอบ ในชื่อการดำเนินการผ่าน Intent ที่เกี่ยวข้องในคลาส Intent:

Kotlin

@RequiresPermission(Manifest.permission.CALL_PHONE)
const val ACTION_CALL = "android.intent.action.CALL"

Java

@RequiresPermission(Manifest.permission.CALL_PHONE)
public static final String ACTION_CALL = "android.intent.action.CALL";

หากจำเป็น คุณใช้ @RequiresPermission แทน @RequiresPermission.Read หรือ @RequiresPermission.Write เมื่อใช้คำอธิบายประกอบ พารามิเตอร์ของเมธอด แต่สำหรับสิทธิ์โดยอ้อม @RequiresPermission ควร ใช้ร่วมกับคำอธิบายประกอบสิทธิ์ในการอ่านหรือเขียนได้

แสดงคำอธิบายประกอบมูลค่า

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

ตัวอย่างเช่น นักพัฒนาซอฟต์แวร์ Java รายใหม่มักเข้าใจผิดว่า <String>.trim() จะนำช่องว่างออกจากสตริงต้นฉบับ ใช้คำอธิบายประกอบ เมธอดที่มีการใช้แฟล็ก @CheckResult ของ <String>.trim() ซึ่งผู้โทรจะไม่ทำอะไรกับค่าการคืนสินค้าของเมธอด

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

Kotlin

@CheckResult(suggest = "#enforcePermission(String,int,int,String)")
abstract fun checkPermission(permission: String, pid: Int, uid: Int): Int

Java

@CheckResult(suggest="#enforcePermission(String,int,int,String)")
public abstract int checkPermission(@NonNull String permission, int pid, int uid);

คำอธิบายประกอบ CallSuper

ใช้คำอธิบายประกอบ @CallSuper เพื่อ ตรวจสอบว่าเมธอดการลบล้างจะเรียกการใช้งานขั้นสูงสุดของเมธอดดังกล่าว

ดังต่อไปนี้ ตัวอย่างจะใส่คำอธิบายประกอบเมธอด onCreate() เพื่อให้แน่ใจว่าเมธอดการลบล้าง การติดตั้งใช้งานเรียก super.onCreate():

Kotlin

@CallSuper
override fun onCreate(savedInstanceState: Bundle?) {
}

Java

@CallSuper
protected void onCreate(Bundle savedInstanceState) {
}

คำอธิบายประกอบ Typedef

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

ใช้ @IntDef และ วันที่ @StringDef เพื่อสร้างคำอธิบายประกอบแบบแจกแจงของชุดจำนวนเต็มและชุดสตริงเพื่อตรวจสอบความถูกต้องอื่นๆ ประเภทการอ้างอิงโค้ดได้

คำอธิบายประกอบ Typedef ใช้ @interface เพื่อประกาศประเภทคำอธิบายประกอบที่แจกแจงใหม่ คำอธิบายประกอบ @IntDef และ @StringDef รวมถึง @Retention ใส่คำอธิบายประกอบให้คำอธิบายประกอบใหม่ และจำเป็นต้องกำหนด ประเภทที่แจกแจง คำอธิบายประกอบ @Retention(RetentionPolicy.SOURCE) จะบอกคอมไพเลอร์ เพื่อเก็บข้อมูลคำอธิบายประกอบที่แจกแจงไว้ในไฟล์ .class

ตัวอย่างต่อไปนี้แสดงขั้นตอนการสร้างคำอธิบายประกอบที่ตรวจสอบว่าค่าผ่านการตรวจสอบหรือไม่ ในฐานะพารามิเตอร์เมธอดจะอ้างอิงหนึ่งในค่าคงที่ที่กำหนดไว้

Kotlin

import androidx.annotation.IntDef
//...
// Define the list of accepted constants and declare the NavigationMode annotation.
@Retention(AnnotationRetention.SOURCE)
@IntDef(NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS)
annotation class NavigationMode

// Declare the constants.
const val NAVIGATION_MODE_STANDARD = 0
const val NAVIGATION_MODE_LIST = 1
const val NAVIGATION_MODE_TABS = 2

abstract class ActionBar {

    // Decorate the target methods with the annotation.
    // Attach the annotation.
    @get:NavigationMode
    @setparam:NavigationMode
    abstract var navigationMode: Int

}

Java

import androidx.annotation.IntDef;
//...
public abstract class ActionBar {
    //...
    // Define the list of accepted constants and declare the NavigationMode annotation.
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
    public @interface NavigationMode {}

    // Declare the constants.
    public static final int NAVIGATION_MODE_STANDARD = 0;
    public static final int NAVIGATION_MODE_LIST = 1;
    public static final int NAVIGATION_MODE_TABS = 2;

    // Decorate the target methods with the annotation.
    @NavigationMode
    public abstract int getNavigationMode();

    // Attach the annotation.
    public abstract void setNavigationMode(@NavigationMode int mode);
}

เมื่อคุณสร้างโค้ดนี้ ระบบจะสร้างคำเตือนหากพารามิเตอร์ mode ไม่ อ้างอิงหนึ่งในค่าคงที่ที่กำหนดไว้ (NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST หรือ NAVIGATION_MODE_TABS)

รวม @IntDef และ @IntRange เพื่อระบุว่า จำนวนเต็มสามารถเป็นได้ทั้งชุดของค่าคงที่หรือค่าภายในช่วง

เปิดใช้การรวมค่าคงที่กับแฟล็ก

หากผู้ใช้รวมค่าคงที่ที่อนุญาตกับ Flag ได้ (เช่น |, &, ^ และอื่นๆ) คุณสามารถกำหนดคำอธิบายประกอบด้วย flag เพื่อตรวจสอบว่าพารามิเตอร์หรือค่าที่ส่งคืนอ้างอิงถึงรูปแบบที่ถูกต้องหรือไม่

ตัวอย่างต่อไปนี้สร้างคำอธิบายประกอบ DisplayOptions ที่มีรายการที่ถูกต้อง ค่าคงที่ DISPLAY_:

Kotlin

import androidx.annotation.IntDef
...

@IntDef(flag = true, value = [
    DISPLAY_USE_LOGO,
    DISPLAY_SHOW_HOME,
    DISPLAY_HOME_AS_UP,
    DISPLAY_SHOW_TITLE,
    DISPLAY_SHOW_CUSTOM
])
@Retention(AnnotationRetention.SOURCE)
annotation class DisplayOptions
...

Java

import androidx.annotation.IntDef;
...

@IntDef(flag=true, value={
        DISPLAY_USE_LOGO,
        DISPLAY_SHOW_HOME,
        DISPLAY_HOME_AS_UP,
        DISPLAY_SHOW_TITLE,
        DISPLAY_SHOW_CUSTOM
})
@Retention(RetentionPolicy.SOURCE)
public @interface DisplayOptions {}

...

เมื่อคุณสร้างโค้ดที่มีแฟล็กคำอธิบายประกอบ ระบบจะสร้างคำเตือนหากพารามิเตอร์ตกแต่ง หรือค่าที่ส่งกลับไม่ได้อ้างอิงรูปแบบที่ถูกต้อง

เก็บคำอธิบายประกอบไว้

@Keep ทำให้แน่ใจได้ว่าคลาสหรือเมธอดที่มีคำอธิบายประกอบจะไม่ถูกนำออกเมื่อโค้ด จะลดขนาดลงขณะสร้าง คำอธิบายประกอบนี้มักจะ เพิ่มลงในวิธีการและคลาสที่มีการเข้าถึงผ่านการทบทวนเพื่อป้องกันไม่ให้คอมไพเลอร์ โดยถือว่าโค้ดไม่มีการใช้งาน

ข้อควรระวัง: คลาสและวิธีที่คุณใส่คำอธิบายประกอบ ที่ใช้ @Keep จะปรากฏใน APK ของแอปเสมอแม้ว่าคุณจะไม่เคย อ้างอิงคลาสและเมธอดเหล่านี้ภายในตรรกะของแอป

หากต้องการทำให้แอปมีขนาดเล็ก ให้พิจารณาว่าคุณจำเป็นต้องเก็บรักษาไว้หรือไม่ คำอธิบายประกอบ @Keep แต่ละรายการในแอปของคุณ หากคุณใช้การสะท้อนเพื่อ เข้าถึงคลาสหรือเมธอดที่มีคำอธิบายประกอบ -if มีเงื่อนไขในกฎ ProGuard โดยระบุคลาส ที่จะทำให้เกิดการตอบสนอง

ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีลดขนาดโค้ดและระบุโค้ดที่ไม่ต้องการนําออก ดูลดขนาด ปรับให้ยากต่อการอ่าน (Obfuscate) และเพิ่มประสิทธิภาพแอป

คำอธิบายประกอบการแสดงโค้ด

ใช้คำอธิบายประกอบต่อไปนี้เพื่อแสดงให้เห็นส่วนที่เฉพาะเจาะจงของโค้ด เช่น คลาส ฟิลด์ หรือแพ็กเกจ

ทำให้เห็นโค้ดสำหรับการทดสอบ

@VisibleForTesting ระบุว่าวิธีการที่มีคำอธิบายประกอบนั้นปรากฏให้เห็นได้มากกว่าปกติที่จำเป็นในการสร้าง สามารถทดสอบได้ คำอธิบายประกอบนี้มีอาร์กิวเมนต์ otherwise ที่ไม่บังคับ ซึ่งทำให้คุณ ระบุระดับการมองเห็นของเมธอดในกรณีที่ไม่ใช่เพื่อความจำเป็นต้องแสดงผลของเมธอด เพื่อการทดสอบ Lint ใช้อาร์กิวเมนต์ otherwise เพื่อบังคับใช้ระดับการเข้าถึงที่ต้องการ

ในตัวอย่างต่อไปนี้ myMethod() โดยปกติคือ private แต่ package-privateสำหรับการทดสอบ ด้วย VisibleForTesting.PRIVATE การระบุ lint จะแสดงข้อความหากมีการเรียกใช้เมธอดนี้จากภายนอก บริบทที่ได้รับอนุญาตโดยการเข้าถึงของ private เช่น มาจากหน่วยการคอมไพล์อื่น

Kotlin

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun myMethod() {
    ...
}

Java

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
void myMethod() { ... }

คุณยังระบุ @VisibleForTesting(otherwise = VisibleForTesting.NONE) ได้ด้วย เพื่อระบุว่ามีเมธอดสำหรับการทดสอบเท่านั้น แบบฟอร์มนี้จะเหมือนกับการใช้ @RestrictTo(TESTS) ทั้ง 2 อย่างจะทำการตรวจสอบ Lint เดียวกัน

จำกัด API

@RestrictTo ระบุว่าการเข้าถึง API ที่มีคำอธิบายประกอบ (แพ็กเกจ คลาส หรือเมธอด) มีจำกัด ดังนี้

คลาสย่อย

ใช้แบบฟอร์มคำอธิบายประกอบ @RestrictTo(RestrictTo.Scope.SUBCLASSES) เพื่อจำกัด สิทธิ์เข้าถึง API ไปยังคลาสย่อยเท่านั้น

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

ห้องสมุด

ใช้แบบฟอร์มคำอธิบายประกอบ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX) เพื่อ จำกัดการเข้าถึง API ไว้เฉพาะไลบรารีของคุณเท่านั้น

มีเพียงรหัสไลบรารีของคุณเท่านั้นที่เข้าถึง API ที่มีคำอธิบายประกอบได้ ซึ่งจะช่วยให้คุณไม่เพียงจัดระเบียบโค้ด ในลำดับชั้นของแพ็กเกจใดก็ได้ ที่คุณต้องการและแชร์ โค้ดในกลุ่มของไลบรารีที่เกี่ยวข้อง ตัวเลือกนี้จะพร้อมใช้งานใน Jetpack อยู่แล้ว ไลบรารีที่มีโค้ดการใช้งานจำนวนมาก ซึ่งไม่ได้มีไว้สำหรับการใช้งานภายนอก แต่ ต้องเป็น public จึงจะแชร์กับไลบรารี Jetpack เสริมต่างๆ ได้

การทดสอบ

ใช้แบบฟอร์มคำอธิบายประกอบ @RestrictTo(RestrictTo.Scope.TESTS) เพื่อป้องกัน ไม่ให้นักพัฒนาแอปเข้าถึง API การทดสอบ

มีเพียงโค้ดการทดสอบเท่านั้นที่เข้าถึง API ที่มีคำอธิบายประกอบได้ วิธีนี้จะป้องกันไม่ให้นักพัฒนาแอปรายอื่นๆ ไม่ให้ใช้ API สำหรับการพัฒนาที่คุณมีไว้เพื่อการทดสอบเท่านั้น