ออกแบบเพื่อการใช้งานที่ราบรื่น

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

ปัญหาความราบรื่นที่พบบ่อยคือเมื่อกระบวนการเบื้องหลังของแอปพลิเคชัน เช่น บริการหรือเครื่องรับการออกอากาศ แสดงกล่องโต้ตอบเพื่อตอบสนองต่อเหตุการณ์บางอย่าง พฤติกรรมนี้อาจดูเหมือนไม่มีพิษมีภัย โดยเฉพาะเมื่อคุณสร้างและทดสอบแอปพลิเคชันแยกกันในโปรแกรมจำลอง อย่างไรก็ตาม เมื่อเรียกใช้แอปพลิเคชันในอุปกรณ์จริง แอปพลิเคชันอาจ ไม่มีโฟกัสของผู้ใช้ในขณะที่กระบวนการทำงานเบื้องหลังแสดงกล่องโต้ตอบ ดังนั้น แอปพลิเคชันของคุณอาจแสดงกล่องโต้ตอบอยู่เบื้องหลัง แอปพลิเคชันที่ใช้งานอยู่ หรืออาจดึงโฟกัสจากแอปพลิเคชันปัจจุบันและ แสดงกล่องโต้ตอบอยู่ด้านหน้าสิ่งที่ผู้ใช้กำลังทำอยู่ (เช่น การโทร ทางโทรศัพท์ เป็นต้น) ลักษณะการทำงานดังกล่าวจะใช้กับแอปพลิเคชันหรือผู้ใช้ไม่ได้

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

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

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

เอกสารนี้จะกล่าวถึงปัญหาที่พบบ่อยเกี่ยวกับความราบรื่นและวิธีหลีกเลี่ยงปัญหาดังกล่าว

อย่าทิ้งข้อมูล

โปรดอย่าลืมว่า Android เป็นแพลตฟอร์มสำหรับอุปกรณ์เคลื่อนที่ แม้ว่าอาจดูเหมือนเป็นเรื่องที่ชัดเจน แต่สิ่งสำคัญที่ควรทราบคือ กิจกรรมอื่น (เช่น แอป "สายโทรศัพท์เข้า") อาจปรากฏขึ้นเหนือกิจกรรมของคุณได้ทุกเมื่อ ซึ่งจะเรียกใช้เมธอด onSaveInstanceState() และ onPause() และอาจส่งผลให้ระบบปิดแอปพลิเคชันของคุณ

หากผู้ใช้กำลังแก้ไขข้อมูลในแอปพลิเคชันของคุณเมื่อกิจกรรมอื่นปรากฏขึ้น แอปพลิเคชันของคุณอาจสูญเสียข้อมูลนั้นเมื่อระบบปิดแอปพลิเคชัน เว้นแต่คุณจะบันทึกงานที่กำลังทำอยู่ก่อน "วิถีแห่ง Android" คือการทำเช่นนั้น กล่าวคือ แอปพลิเคชัน Android ที่ยอมรับหรือแก้ไขอินพุตควร ลบล้างเมธอด onSaveInstanceState() และบันทึกสถานะในลักษณะที่เหมาะสม เมื่อผู้ใช้กลับมาที่แอปพลิเคชัน ผู้ใช้ควรจะดึงข้อมูลของตนเองได้

ตัวอย่างคลาสสิกของการใช้ลักษณะการทำงานนี้อย่างเหมาะสมคือแอปพลิเคชันอีเมล หาก ผู้ใช้กำลังเขียนอีเมลเมื่อกิจกรรมอื่นเริ่มขึ้น แอปพลิเคชัน ควรบันทึกอีเมลที่กำลังเขียนเป็นฉบับร่าง

อย่าเปิดเผยข้อมูลดิบ

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

"วิธีของ Android" คือการสร้าง ContentProvider เพื่อแสดงข้อมูลต่อแอปพลิเคชันอื่นๆ ผ่าน API ที่สะอาด มีการวางแผนมาอย่างดี และดูแลรักษาได้ การใช้ ContentProvider คล้ายกับการแทรกอินเทอร์เฟซภาษา Java เพื่อแยกและ จัดองค์ประกอบโค้ด 2 ส่วนที่เชื่อมโยงกันอย่างแน่นหนา ซึ่งหมายความว่าคุณจะ แก้ไขรูปแบบภายในของข้อมูลได้โดยไม่ต้องเปลี่ยนอินเทอร์เฟซที่ ContentProvider แสดง และจะไม่ส่งผลกระทบต่อแอปพลิเคชันอื่นๆ

อย่าขัดจังหวะผู้ใช้

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

กล่าวคือ อย่าเรียกใช้ startActivity() จาก BroadcastReceiver หรือบริการที่ทำงานใน เบื้องหลัง การทำเช่นนี้จะขัดจังหวะแอปพลิเคชันที่กำลังทำงานอยู่ และทำให้ผู้ใช้รู้สึกหงุดหงิด ที่แย่กว่านั้นคือ กิจกรรมของคุณอาจ กลายเป็น "ขโมยการกดแป้น" และรับข้อมูลบางส่วนที่ผู้ใช้กำลัง ป้อนให้กับกิจกรรมก่อนหน้า ซึ่งอาจเป็นข่าวร้าย ทั้งนี้ขึ้นอยู่กับสิ่งที่แอปพลิเคชันของคุณทำ

คุณควรใช้ NotificationManager เพื่อตั้งค่าการแจ้งเตือนแทนการสร้าง UI ของกิจกรรมจากเบื้องหลังโดยตรง โดยจะปรากฏใน แถบสถานะ และผู้ใช้สามารถคลิกได้ตามสะดวกเพื่อดู สิ่งที่แอปพลิเคชันของคุณแสดง

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

หากมีหลายอย่างที่ต้องทำ ดำเนินการในชุดข้อความ

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

โดยค่าเริ่มต้น โค้ดทั้งหมดใน Activity รวมถึง View ทั้งหมดจะทำงานใน เธรดเดียวกัน ซึ่งเป็นเธรดเดียวกันที่จัดการเหตุการณ์ UI ด้วย ตัวอย่างเช่น เมื่อผู้ใช้กดปุ่ม ระบบจะเพิ่มเหตุการณ์การกดปุ่มลงในคิวของเทรดหลักของกิจกรรม ระบบตัวแฮนเดิลเหตุการณ์ต้องนำเหตุการณ์นั้นออกจากคิวและจัดการอย่างรวดเร็ว หากไม่ทำเช่นนั้น ระบบจะสรุปหลังจากผ่านไป 2-3 วินาทีว่า แอปพลิเคชันค้างและเสนอให้ปิดแอปพลิเคชันสำหรับผู้ใช้

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

อย่าใส่ข้อมูลมากเกินไปในหน้าจอกิจกรรมเดียว

แอปพลิเคชันที่คุ้มค่าต่อการใช้งานมักจะมีหน้าจอที่แตกต่างกันหลายหน้าจอ เมื่อออกแบบหน้าจอของ UI อย่าลืมใช้หลายอินสแตนซ์ของออบเจ็กต์ Activity

คุณอาจตีความ Activity ว่าคล้ายกับ Java Applet เนื่องจากเป็นจุดแรกเข้าของแอปพลิเคชัน ทั้งนี้ขึ้นอยู่กับพื้นฐานการพัฒนาของคุณ อย่างไรก็ตาม คำอธิบายดังกล่าวไม่ถูกต้องนัก เนื่องจากคลาสย่อยของ Applet เป็นจุดแรกเข้าเดียวสำหรับ Java Applet แต่ Activity ควรเป็น จุดแรกเข้าหนึ่งในหลายๆ จุดที่เป็นไปได้สำหรับแอปพลิเคชันของคุณ ความแตกต่างเพียงอย่างเดียวระหว่างกิจกรรม "หลัก" กับกิจกรรมอื่นๆ ที่คุณอาจมีคือ กิจกรรม "หลัก" เป็นกิจกรรมเดียวที่แสดงความสนใจในการดำเนินการ "android.intent.action.MAIN" ในไฟล์ AndroidManifest.xml

ดังนั้นเมื่อออกแบบแอปพลิเคชัน ให้คิดว่าแอปพลิเคชันของคุณเป็นสหพันธ์ ของออบเจ็กต์กิจกรรม ซึ่งจะทำให้โค้ดของคุณดูแลรักษาได้ง่ายขึ้นมากในระยะยาว และยังส่งผลดีต่อประวัติแอปพลิเคชันและโมเดล "Backstack" ของ Android อีกด้วย

ขยายธีมของระบบ

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

ออกแบบ UI ให้ทำงานกับความละเอียดหน้าจอหลายระดับ

อุปกรณ์ที่ใช้ Android จะรองรับความละเอียดหน้าจอที่แตกต่างกัน บางรุ่นยังเปลี่ยนความละเอียดได้ทันที เช่น โดยการเปลี่ยนเป็นโหมดแนวนอน คุณต้องตรวจสอบว่าเลย์เอาต์และ Drawable มีความยืดหยุ่นเพียงพอที่จะแสดงอย่างถูกต้องบนหน้าจออุปกรณ์ต่างๆ

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

สมมติว่าเครือข่ายช้า

อุปกรณ์ Android จะมาพร้อมตัวเลือกการเชื่อมต่อเครือข่ายที่หลากหลาย ทุกรุ่น จะมีข้อกำหนดในการเข้าถึงข้อมูล แม้ว่าบางรุ่นจะเร็วกว่ารุ่นอื่นๆ อย่างไรก็ตาม ตัวหารร่วมที่ต่ำที่สุดคือ GPRS ซึ่งเป็นบริการอินเทอร์เน็ตที่ไม่ใช่ 3G สำหรับเครือข่าย GSM แม้แต่อุปกรณ์ที่รองรับ 3G ก็จะใช้เวลาส่วนใหญ่ในเครือข่ายที่ไม่ใช่ 3G ดังนั้นเครือข่ายที่ช้าจะยังคงเป็นเรื่องจริงไปอีกนาน

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

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

อย่าคิดว่าผู้ใช้มีหน้าจอสัมผัสหรือแป้นพิมพ์

Android จะรองรับรูปแบบของอุปกรณ์เคลื่อนที่ที่หลากหลาย ซึ่งเป็นวิธีที่ดูดีในการบอกว่าอุปกรณ์ Android บางรุ่นจะมีแป้นพิมพ์ "QWERTY" แบบเต็ม ในขณะที่อุปกรณ์รุ่นอื่นๆ จะมีแป้นพิมพ์ 40 ปุ่ม 12 ปุ่ม หรือการกำหนดค่าปุ่มอื่นๆ ในทำนองเดียวกัน อุปกรณ์บางเครื่องจะมีหน้าจอสัมผัส แต่หลายเครื่องจะไม่มี

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

ประหยัดแบตเตอรี่ของอุปกรณ์

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

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

ผู้ใช้ค่อนข้างฉลาด หากโปรแกรมของคุณใช้พลังงานมาก คุณก็มั่นใจได้ว่าผู้ใช้จะสังเกตเห็น สิ่งเดียวที่คุณมั่นใจได้ในตอนนั้นคือโปรแกรมของคุณจะอยู่ได้ไม่นาน