การใช้เครื่องมือตรวจสอบโค้ด เช่น 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.2") }
ดึงดูด
dependencies { implementation 'androidx.annotation:annotation:1.8.2' }
หากคุณใช้คำอธิบายประกอบในโมดูลไลบรารีของคุณเอง คำอธิบายประกอบจะรวมไว้เป็นส่วนหนึ่งของ
อาร์ติแฟกต์ 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
เครื่องมือบิลด์จะสร้างคำเตือนใน 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 สำหรับการพัฒนาที่คุณมีไว้เพื่อการทดสอบเท่านั้น