แอป Android ขัดข้องทุกครั้งที่มีการออกที่ไม่คาดคิดซึ่งเกิดจาก
ข้อยกเว้นหรือสัญญาณที่ไม่มีการจัดการ แอปที่เขียนโดยใช้ Java หรือ Kotlin
หากแสดงข้อผิดพลาดที่ไม่มีการจัดการ ซึ่งแสดงโดย
Throwable
CANNOT TRANSLATE
แอปที่เขียนโดยใช้โค้ดเครื่องหรือ C++ ขัดข้องหากมีการจัดการ
เช่น SIGSEGV
ในระหว่างการดำเนินการ
เมื่อแอปขัดข้อง Android จะหยุดกระบวนการของแอปและแสดงกล่องโต้ตอบ เพื่อแจ้งผู้ใช้ว่าแอปหยุดทำงานแล้ว ดังที่แสดงในรูปที่ 1
แอปไม่จำเป็นต้องทำงานอยู่ในเบื้องหน้าเพื่อให้แอปขัดข้อง ทุกแอป หรือแม้กระทั่งคอมโพเนนต์อย่าง Broadcast Receiver หรือผู้ให้บริการเนื้อหาที่ ที่ทำงานอยู่ในเบื้องหลัง อาจทำให้แอปขัดข้อง ข้อขัดข้องเหล่านี้ มักทำให้ผู้ใช้สับสนเพราะไม่ได้มีส่วนร่วมกับแอปของคุณอย่างสม่ำเสมอ
หากแอปพบข้อขัดข้อง คุณสามารถใช้คำแนะนำในหน้านี้เพื่อ วินิจฉัยและแก้ไขปัญหา
ตรวจหาปัญหา
คุณอาจไม่ทราบว่าผู้ใช้ของคุณพบข้อขัดข้องเมื่อ ที่พวกเขาใช้แอปของคุณ หากเผยแพร่แอปแล้ว คุณสามารถใช้ Android Vitals เพื่อดูอัตราการขัดข้องของแอป
Android Vitals
Android Vitals ช่วยคุณตรวจสอบและปรับปรุงอัตราการขัดข้องของแอปได้ Android Vitals วัดอัตราการขัดข้องหลายอย่าง ดังนี้
- อัตราการขัดข้อง: เปอร์เซ็นต์ของผู้ใช้ที่ใช้งานอยู่รายวันซึ่ง ก็พบข้อขัดข้องในทุกประเภท
อัตราการขัดข้องที่ผู้ใช้รับรู้: เปอร์เซ็นต์ของผู้ใช้ที่ใช้งานอยู่รายวัน ที่พบข้อขัดข้องอย่างน้อย 1 ครั้งขณะใช้แอปของคุณ (การขัดข้องที่ผู้ใช้รับรู้) ระบบถือว่าแอปมีการใช้งานอยู่ หากมีการแสดงกิจกรรมหรือการดำเนิน บริการที่ทำงานอยู่เบื้องหน้า
อัตราการขัดข้องหลายครั้ง: เปอร์เซ็นต์ของผู้ใช้ที่ใช้งานอยู่รายวันซึ่ง พบข้อขัดข้องอย่างน้อย 2 ครั้ง
ผู้ใช้ที่ใช้งานอยู่รายวันคือผู้ใช้ที่ไม่ซ้ำที่ใช้แอปของคุณ ในวันเดียวบนอุปกรณ์เดียว ซึ่งอาจมีมากกว่าหลายเซสชัน หากผู้ใช้ใช้แอปของคุณบนอุปกรณ์มากกว่า 1 เครื่องใน 1 วัน อุปกรณ์แต่ละเครื่องจะรวม กับจำนวนผู้ใช้ที่ใช้งานอยู่ในวันนั้น หากมีผู้ใช้หลายคนใช้อุปกรณ์เดียวกันในวันเดียวกัน ก็จะนับเป็นผู้ใช้ที่ใช้งานอยู่ 1 คน
อัตราการขัดข้องที่ผู้ใช้รับรู้เป็น Vitals หลักซึ่งส่งผลต่อ การค้นพบได้ของแอปคุณใน Google Play มีความสำคัญเพราะเกิดข้อขัดข้อง มักเกิดขึ้นเมื่อผู้ใช้มีส่วนร่วมกับแอป ซึ่งทำให้เกิด ขัดข้อง
Play ได้กำหนดเกณฑ์ลักษณะการทำงานที่ไม่ถูกต้อง 2 เกณฑ์ในเมตริกนี้ไว้ดังนี้
- เกณฑ์ลักษณะการทำงานที่ไม่ถูกต้องโดยรวม: อย่างน้อย 1.09% ของผู้ใช้ที่ใช้งานอยู่รายวัน พบการขัดข้องที่ผู้ใช้รับรู้ในอุปกรณ์ทุกรุ่น
- เกณฑ์ลักษณะการทำงานที่ไม่ถูกต้องต่ออุปกรณ์: อย่างน้อย 8% ของผู้ใช้ที่ใช้งานอยู่รายวัน พบการขัดข้องที่ผู้ใช้รับรู้สำหรับอุปกรณ์รุ่นเดียว
หากแอปเกินเกณฑ์ลักษณะการทํางานที่ไม่ถูกต้องโดยรวม อาจเป็นไปได้ว่า ค้นพบได้น้อยลงในทุกอุปกรณ์ หากแอปมีลักษณะการทำงานที่ไม่ถูกต้องในแต่ละอุปกรณ์ ในอุปกรณ์บางประเภท ซึ่งมีแนวโน้มที่จะค้นพบได้น้อยลงในอุปกรณ์เหล่านั้น และอาจแสดงคำเตือนในข้อมูลผลิตภัณฑ์ใน Store ของคุณ
Android Vitals สามารถแจ้งเตือนคุณผ่าน Play Console เมื่อแอปแสดงข้อขัดข้องที่บ่อยเกินไป
สำหรับข้อมูลเกี่ยวกับวิธีที่ Google Play รวบรวมข้อมูล Android Vitals โปรดดู Play Console เอกสารประกอบ
วินิจฉัยข้อขัดข้อง
เมื่อคุณพบว่าแอปรายงานข้อขัดข้องแล้ว ระบบจะ ขั้นตอนถัดไปคือการวิเคราะห์ การแก้ปัญหาข้อขัดข้องอาจเป็นเรื่องยาก อย่างไรก็ตาม หากคุณสามารถระบุสาเหตุที่แท้จริงของ ซึ่งก็น่าจะหาวิธีแก้ปัญหานั้นได้
มีหลายกรณีที่อาจทำให้แอปของคุณขัดข้อง เหตุผลส่วนหนึ่ง ได้แก่ ก็ง่าย เช่น ตรวจหาค่า Null หรือสตริงว่างเปล่า ซับซ้อน เช่น การส่งอาร์กิวเมนต์ที่ไม่ถูกต้องไปยัง API หรือแม้กระทั่งแบบหลายเธรดที่ซับซ้อน การโต้ตอบ
ข้อขัดข้องใน Android จะสร้างสแต็กเทรซซึ่งเป็นสแนปชอตของลำดับของ ฟังก์ชันที่ฝังไว้ซึ่งเรียกใช้ในโปรแกรมของคุณจนถึงเวลาที่ขัดข้อง คุณสามารถ ดูสแต็กเทรซข้อขัดข้องใน Android Vitals
วิธีอ่านสแต็กเทรซ
ขั้นตอนแรกในการแก้ไขข้อขัดข้องคือการระบุตำแหน่งที่เกิดปัญหา คุณสามารถ ใช้สแต็กเทรซที่มีอยู่ในรายละเอียดของรายงานหากคุณใช้ Play คอนโซลหรือเอาต์พุตของเครื่องมือ logcat หากคุณ ไม่มีสแต็กเทรซที่ใช้ได้ คุณควรจำลองข้อขัดข้องไว้ในเครื่อง ด้วยการทดสอบแอปด้วยตนเองหรือโดยการติดต่อผู้ใช้ที่ได้รับผลกระทบ และ จำลองให้เกิดซ้ำขณะใช้ Logcat
การติดตามต่อไปนี้แสดงตัวอย่างข้อขัดข้องในแอปที่เขียนโดยใช้ Java ภาษาโปรแกรม:
--------- beginning of crash
AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.developer.crashsample, PID: 3686
java.lang.NullPointerException: crash sample
at com.android.developer.crashsample.MainActivity$1.onClick(MainActivity.java:27)
at android.view.View.performClick(View.java:6134)
at android.view.View$PerformClick.run(View.java:23965)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:6440)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:746)
--------- beginning of system
สแต็กเทรซจะแสดงข้อมูล 2 ส่วนที่สำคัญต่อการแก้ไขข้อบกพร่อง ขัดข้อง:
- ประเภทของข้อยกเว้นที่ส่ง
- ส่วนของโค้ดที่มีการยกเว้น
ประเภทของข้อยกเว้นที่ส่งมัก
บ่งชี้ได้ชัดเจนว่า
ผิด พิจารณาว่าเป็น
IOException
OutOfMemoryError
หรือดูเอกสารเกี่ยวกับคลาสข้อยกเว้น
คลาส เมธอด ไฟล์ และหมายเลขบรรทัดของไฟล์ต้นฉบับที่มีข้อยกเว้น แสดงในบรรทัดที่ 2 ของสแต็กเทรซ สำหรับแต่ละฟังก์ชันที่ ถูกเรียก อีกบรรทัดหนึ่งแสดงไซต์การเรียกใช้ก่อนหน้า (เรียกว่าสแต็กเฟรม) เมื่อเดินขึ้นสแต็กและตรวจสอบโค้ดแล้ว คุณอาจพบสถานที่ที่ ส่งค่าที่ไม่ถูกต้อง หากโค้ดไม่ปรากฏในสแต็กเทรซ เป็นไปได้ว่ามีที่ใดที่หนึ่งคุณส่งพารามิเตอร์ที่ไม่ถูกต้องไปยังอะซิงโครนัส คุณสามารถหาสาเหตุได้ง่ายๆ ด้วยการตรวจสอบแต่ละบรรทัดของ สแต็กเทรซ ค้นหาคลาส API ที่คุณใช้ และยืนยันว่า ที่ส่งเป็นพารามิเตอร์ที่ถูกต้อง และคุณเรียกใช้พารามิเตอร์นั้นจากสถานที่ที่ อนุญาต
สแต็กเทรซสำหรับแอปที่มีโค้ด C และ C++ จะทำงานในลักษณะเดียวกัน
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/foo/bar:10/123.456/78910:user/release-keys'
ABI: 'arm64'
Timestamp: 2020-02-16 11:16:31+0100
pid: 8288, tid: 8288, name: com.example.testapp >>> com.example.testapp <<<
uid: 1010332
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
Cause: null pointer dereference
x0 0000007da81396c0 x1 0000007fc91522d4 x2 0000000000000001 x3 000000000000206e
x4 0000007da8087000 x5 0000007fc9152310 x6 0000007d209c6c68 x7 0000007da8087000
x8 0000000000000000 x9 0000007cba01b660 x10 0000000000430000 x11 0000007d80000000
x12 0000000000000060 x13 0000000023fafc10 x14 0000000000000006 x15 ffffffffffffffff
x16 0000007cba01b618 x17 0000007da44c88c0 x18 0000007da943c000 x19 0000007da8087000
x20 0000000000000000 x21 0000007da8087000 x22 0000007fc9152540 x23 0000007d17982d6b
x24 0000000000000004 x25 0000007da823c020 x26 0000007da80870b0 x27 0000000000000001
x28 0000007fc91522d0 x29 0000007fc91522a0
sp 0000007fc9152290 lr 0000007d22d4e354 pc 0000007cba01b640
backtrace:
#00 pc 0000000000042f89 /data/app/com.example.testapp/lib/arm64/libexample.so (com::example::Crasher::crash() const)
#01 pc 0000000000000640 /data/app/com.example.testapp/lib/arm64/libexample.so (com::example::runCrashThread())
#02 pc 0000000000065a3b /system/lib/libc.so (__pthread_start(void*))
#03 pc 000000000001e4fd /system/lib/libc.so (__start_thread)
หากไม่เห็นข้อมูลคลาสและระดับฟังก์ชันในสแต็กเทรซดั้งเดิม คุณอาจต้อง สร้างไฟล์สัญลักษณ์การแก้ไขข้อบกพร่องของระบบ และอัปโหลดไปยัง Google Play Console สำหรับข้อมูลเพิ่มเติม โปรดดู ถอดรหัสซอร์สโค้ดที่สร้างความสับสนของสแต็กเทรซข้อขัดข้อง สำหรับข้อมูลทั่วไปเกี่ยวกับการขัดข้องของระบบ โปรดดู การวิเคราะห์ข้อขัดข้องของระบบ
เคล็ดลับในการจำลองข้อขัดข้อง
เป็นไปได้ว่าคุณอาจไม่สามารถทำให้ปัญหาเกิดซ้ำได้ด้วยการเริ่มต้น โปรแกรมจำลองหรือการเชื่อมต่ออุปกรณ์กับคอมพิวเตอร์ สภาพแวดล้อมในการพัฒนาซอฟต์แวร์ มักจะมีทรัพยากรมากกว่า เช่น แบนด์วิดท์ หน่วยความจำ และพื้นที่เก็บข้อมูล ใช้เมนู ประเภทข้อยกเว้นเพื่อระบุว่าอาจเป็นทรัพยากรที่ขาดแคลน หรือ ค้นหาความสัมพันธ์ระหว่างเวอร์ชัน Android ประเภทอุปกรณ์ หรือแอป เวอร์ชัน
ข้อผิดพลาดของหน่วยความจํา
หากคุณมี
OutOfMemoryError
คุณสามารถสร้างโปรแกรมจำลองที่มีความจุ
หน่วยความจำต่ำเพื่อทดสอบได้ รูป
2 แสดงการตั้งค่าตัวจัดการ AVD ที่คุณสามารถควบคุมจำนวนหน่วยความจำ
อุปกรณ์
ข้อยกเว้นเครือข่าย
เนื่องจากผู้ใช้มักย้ายเข้าและออกจากการครอบคลุมเครือข่ายมือถือหรือ Wi-Fi ใน โดยทั่วไปข้อยกเว้นเครือข่ายแอปพลิเคชันไม่ควรถือเป็นข้อผิดพลาด แทนที่จะเป็นสภาวะการทำงานปกติ แบบที่ไม่คาดคิด
หากคุณต้องการสร้างข้อยกเว้นของเครือข่ายซ้ำ เช่น
UnknownHostException
จากนั้นลองเปิดโหมดบนเครื่องบินในขณะที่แอปพลิเคชันพยายามใช้
เครือข่าย
อีกตัวเลือกหนึ่งคือการลดคุณภาพของเครือข่ายในโปรแกรมจำลองโดย
การเลือกการจำลองความเร็วของเครือข่ายและ/หรือความล่าช้าของเครือข่าย คุณสามารถใช้
การตั้งค่าความเร็วและเวลาในการตอบสนองในเครื่องมือจัดการ AVD หรือจะเริ่มโปรแกรมจำลองก็ได้
ที่มีแฟล็ก -netdelay
และ -netspeed
ดังที่แสดงใน
ตัวอย่างบรรทัดคำสั่ง
emulator -avd [your-avd-image] -netdelay 20000 -netspeed gsm
ตัวอย่างนี้ตั้งการหน่วงเวลา 20 วินาทีสำหรับคำขอเครือข่ายและการอัปโหลดทั้งหมด และความเร็วในการดาวน์โหลด 14.4 Kbps สําหรับข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือกบรรทัดคำสั่ง สำหรับโปรแกรมจำลอง ให้ดูที่ เริ่มโปรแกรมจำลองจากบรรทัดคำสั่ง
การอ่านด้วย Logcat
เมื่อคุณสามารถสร้างขั้นตอนที่ทำให้เกิดข้อขัดข้องซ้ำแล้ว คุณก็สามารถใช้เครื่องมืออย่างเช่น
logcat
เพื่อดูข้อมูลเพิ่มเติม
เอาต์พุต Logcat จะแสดงข้อความบันทึกอื่นๆ ที่คุณพิมพ์ไว้
กับผู้อื่นจากระบบ อย่าลืมปิดส่วนเสริม
Log
ระบุว่าคุณ
เพิ่มเพราะการพิมพ์ทำให้สิ้นเปลือง CPU และแบตเตอรี่ในขณะที่แอปของคุณ
วิ่งอยู่
ป้องกันข้อขัดข้องที่เกิดจากข้อยกเว้นตัวชี้แบบ Null
ข้อยกเว้นตัวชี้แบบ Null (ระบุโดยประเภทข้อผิดพลาดรันไทม์
NullPointerException
) เกิดขึ้นเมื่อคุณพยายามเข้าถึงออบเจ็กต์ที่
ไม่มีข้อมูล ซึ่งโดยปกติแล้วจะเป็นการเรียกใช้เมธอดหรือเข้าถึงสมาชิก ตัวชี้ค่าว่าง
"ข้อยกเว้น" เป็นสาเหตุที่ใหญ่ที่สุดที่ทำให้แอปขัดข้องใน Google Play วัตถุประสงค์ของ
null คือการแสดงว่าอ็อบเจกต์หายไป เช่น ยังไม่ได้
สร้างหรือมอบหมายแล้ว ในการหลีกเลี่ยงข้อยกเว้นตัวชี้แบบมีค่า คุณจะต้องตรวจสอบว่า
ที่ออบเจ็กต์ที่อ้างอิงที่คุณทำงานอยู่ด้วยนั้นไม่เป็นค่าว่างก่อนที่จะเรียก
กับวิดีโอหรือพยายามเข้าถึงสมาชิกของตนเอง หากการอ้างอิงวัตถุคือ
null จัดการกรณีนี้ได้ดี (เช่น ออกจากเมธอดก่อนที่จะดำเนินการ
การดำเนินการทั้งหมดกับการอ้างอิงออบเจ็กต์และเขียนข้อมูลลงในบันทึกการแก้ไขข้อบกพร่อง)
เนื่องจากไม่ต้องการให้มีการตรวจสอบ Null ในทุกพารามิเตอร์ของทุกเมธอด คุณสามารถใช้ IDE หรือประเภทของออบเจ็กต์เพื่อแสดง ความสามารถในการเว้นว่าง
ภาษาโปรแกรม Java
ส่วนต่อไปนี้ใช้กับภาษาโปรแกรม Java
คำเตือนเวลาคอมไพล์
ใส่คำอธิบายประกอบให้กับเมธอดของคุณ และแสดงผลค่าด้วย
@Nullable
และ
@NonNull
เพื่อรับเวลาคอมไพล์
จาก IDE คำเตือนเหล่านี้จะแจ้งให้คุณคาดหวังออบเจ็กต์ที่ไม่มีข้อมูล
การตรวจสอบที่เป็นค่าว่างเหล่านี้มีไว้สำหรับออบเจ็กต์ที่คุณทราบว่าอาจเป็นค่าว่าง ข้อยกเว้นสำหรับ
ออบเจ็กต์ @NonNull
เป็นตัวบ่งบอกถึงข้อผิดพลาดในโค้ดของคุณซึ่งจำเป็นต้อง
ที่อยู่
คอมไพล์ข้อผิดพลาดเกี่ยวกับเวลา
เนื่องจากค่า Null ควรมีความหมาย คุณจึงฝังค่าไว้ในประเภทที่คุณใช้ได้
เพื่อให้มีการตรวจสอบเวลาคอมไพล์สำหรับ Null ถ้าคุณทราบว่าวัตถุสามารถ
null และ nullability นั้นควรได้รับการจัดการ คุณสามารถรวมค่านี้ไว้ในออบเจ็กต์เช่น
Optional
คุณควรเลือกใช้ประเภทที่แสดงถึงความสามารถในการเว้นว่างเสมอ
Kotlin
ใน Kotlin
ความสามารถในการเว้นว่าง
เป็นส่วนหนึ่งของระบบประเภท ตัวอย่างเช่น ต้องประกาศตัวแปรจาก
ค่าเริ่มต้นเป็นค่าว่างหรือค่าที่ไม่เป็นโมฆะ ประเภทที่เว้นว่างได้จะมี ?
กำกับไว้:
// non-null
var s: String = "Hello"
// null
var s: String? = "Hello"
ไม่สามารถกำหนดค่าตัวแปรที่ไม่เป็นค่าว่างและตัวแปรที่เป็นค่าว่างได้ ต้องมีการตรวจสอบค่า Null ก่อนที่จะนำไปใช้เป็นที่ไม่ใช่ Null
หากไม่ต้องการตรวจหา Null อย่างชัดแจ้ง ให้ใช้การโทรที่ปลอดภัยของ ?.
โอเปอเรเตอร์:
val length: Int? = string?.length // length is a nullable int
// if string is null, then length is null
แนวทางปฏิบัติแนะนำคือตรวจสอบว่าคุณจัดการกับกรณี Null ของออบเจ็กต์ Null
หรือแอปอาจเสียสถานะที่ไม่คาดคิด หากแอปพลิเคชันของคุณไม่ขัดข้อง
เมื่อใช้ NullPointerException
แล้ว คุณจะไม่ทราบเลยว่ามีข้อผิดพลาดเหล่านี้
วิธีตรวจสอบค่า Null มีดังนี้
if
ครั้งval length = if(string != null) string.length else 0
เนื่องจาก Smartcast และ Null Check ทำให้คอมไพเลอร์ Kotlin ทราบว่า ค่าสตริงต้องไม่เป็นค่าว่าง จึงช่วยให้คุณใช้การอ้างอิงได้โดยตรง โดยไม่ต้องใช้ผู้ให้บริการการโทรที่ปลอดภัย
-
โอเปอเรเตอร์นี้ช่วยให้คุณระบุ "หากออบเจ็กต์ไม่ใช่ค่าว่าง" ให้แสดงผล object; หากไม่เช่นนั้น ให้คืนสินค้าอื่น"
val length = string?.length ?: 0
คุณยังรับ NullPointerException
ใน Kotlin ได้ ปัจจัยต่อไปนี้คือ
สถานการณ์ทั่วไป
- เมื่อคุณโยน
NullPointerException
อย่างชัดแจ้ง - เมื่อคุณใช้
โอเปอเรเตอร์
!!
ในการยืนยันค่าว่าง โอเปอเรเตอร์นี้จะแปลงค่าใดๆ เป็นประเภทที่ไม่เป็นค่าว่าง โดยส่งNullPointerException
หากค่าเป็น Null - เมื่อเข้าถึงการอ้างอิง Null ของประเภทแพลตฟอร์ม
ประเภทแพลตฟอร์ม
ประเภทแพลตฟอร์มคือการประกาศออบเจ็กต์ที่มาจาก Java ประเภทนี้ได้รับการดูแลเป็นพิเศษ การตรวจสอบที่เป็นค่าว่างไม่ได้มีการบังคับใช้ ดังนั้นการรับประกันที่ไม่เป็นค่าว่างจึงเหมือนกับใน Java เมื่อคุณเข้าถึงการอ้างอิงประเภทแพลตฟอร์ม Kotlin จะไม่สร้างคอมไพล์ เกี่ยวกับเวลา แต่การอ้างอิงเหล่านี้อาจทำให้เกิดข้อผิดพลาดรันไทม์ได้ โปรดดูข้อมูลต่อไปนี้ ตัวอย่างจากเอกสารประกอบของ Kotlin
val list = ArrayList<String>() // non-null (constructor result) list.add("Item")
val size = list.size // non-null (primitive int) val item = list[0] // platform
type inferred (ordinary Java object) item.substring(1) // allowed, may throw an
// exception if item == null
Kotlin ใช้การอนุมานประเภทเมื่อมีการกำหนดค่าแพลตฟอร์มให้กับ Kotlin
หรือคุณจะกำหนด
ประเภทที่ควรทราบก็ได้ วิธีที่ดีที่สุดในการตรวจสอบว่า
สถานะค่า Nullability ที่ถูกต้องของการอ้างอิงที่มาจาก Java คือการใช้ Nullability
คำอธิบายประกอบ (เช่น @Nullable
) ในโค้ด Java คอมไพเลอร์ Kotlin
จะแสดงการอ้างอิงเหล่านี้เป็นประเภทที่ไม่มีข้อมูลหรือไม่สามารถมีค่าได้จริง ไม่ใช่
ประเภทแพลตฟอร์ม
Java Jetpack API มีการใส่คำอธิบายประกอบด้วย @Nullable
หรือ @NonNull
ตามความจำเป็น
และได้ใช้แนวทางที่คล้ายกันนี้ใน
Android 11 SDK
ประเภทที่มาจาก SDK นี้ซึ่งใช้ใน Kotlin จะแสดงเป็น
ประเภท nullable หรือ ไม่ใช่ null ที่ถูกต้อง
เนื่องจากระบบประเภทของ Kotlin เราพบว่าแอปมีจำนวนลดลงอย่างมาก
ขัดข้อง NullPointerException
รายการ เช่น แอป Google Home พบว่า
การลดลงของข้อขัดข้องที่เกิดจากข้อยกเว้นตัวชี้แบบ Null ในปีที่เกิดปัญหา
ย้ายการพัฒนาฟีเจอร์ใหม่ไปยัง Kotlin