ข้อขัดข้อง

แอป Android ขัดข้องทุกครั้งที่มีการออกที่ไม่คาดคิดซึ่งเกิดจาก ข้อยกเว้นหรือสัญญาณที่ไม่มีการจัดการ แอปที่เขียนโดยใช้ Java หรือ Kotlin หากแสดงข้อผิดพลาดที่ไม่มีการจัดการ ซึ่งแสดงโดย Throwable CANNOT TRANSLATE แอปที่เขียนโดยใช้โค้ดเครื่องหรือ C++ ขัดข้องหากมีการจัดการ เช่น SIGSEGV ในระหว่างการดำเนินการ

เมื่อแอปขัดข้อง Android จะหยุดกระบวนการของแอปและแสดงกล่องโต้ตอบ เพื่อแจ้งผู้ใช้ว่าแอปหยุดทำงานแล้ว ดังที่แสดงในรูปที่ 1

ข้อขัดข้องของแอปในอุปกรณ์ Android

รูปที่ 1 ข้อขัดข้องของแอปในอุปกรณ์ Android

แอปไม่จำเป็นต้องทำงานอยู่ในเบื้องหน้าเพื่อให้แอปขัดข้อง ทุกแอป หรือแม้กระทั่งคอมโพเนนต์อย่าง 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 ที่คุณสามารถควบคุมจำนวนหน่วยความจำ อุปกรณ์

การตั้งค่าหน่วยความจำในตัวจัดการ AVD

รูปที่ 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 คำเตือนเหล่านี้จะแจ้งให้คุณคาดหวังออบเจ็กต์ที่ไม่มีข้อมูล

คำเตือนเกี่ยวกับข้อยกเว้นตัวชี้ Null

การตรวจสอบที่เป็นค่าว่างเหล่านี้มีไว้สำหรับออบเจ็กต์ที่คุณทราบว่าอาจเป็นค่าว่าง ข้อยกเว้นสำหรับ ออบเจ็กต์ @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 ทราบว่า ค่าสตริงต้องไม่เป็นค่าว่าง จึงช่วยให้คุณใช้การอ้างอิงได้โดยตรง โดยไม่ต้องใช้ผู้ให้บริการการโทรที่ปลอดภัย

  • ?: โอเปอเรเตอร์ของ Elvis

    โอเปอเรเตอร์นี้ช่วยให้คุณระบุ "หากออบเจ็กต์ไม่ใช่ค่าว่าง" ให้แสดงผล 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