portaldacalheta.pt
  • หลัก
  • นักลงทุนและเงินทุน
  • ทีมแบบกระจาย
  • เทคโนโลยี
  • แนวโน้ม
มือถือ

เคล็ดลับและเครื่องมือสำหรับการเพิ่มประสิทธิภาพแอพ Android



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

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



สร้างแอปที่ดีขึ้น: รูปแบบประสิทธิภาพของ Android



การทดสอบความอดทนของผู้ใช้เป็นทางลัดในการถอนการติดตั้ง ทวีต

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



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

เคล็ดลับประสิทธิภาพ

ทฤษฎีเพียงพอนี่คือรายการบางสิ่งที่คุณควรพิจารณาหากประสิทธิภาพมีความสำคัญกับคุณ



1. String กับ StringBuilder

สมมติว่าคุณมี String และด้วยเหตุผลบางอย่างคุณต้องการต่อท้าย Strings มากกว่า 10,000 ครั้ง โค้ดอาจมีลักษณะดังนี้

String string = 'hello'; for (int i = 0; i <10000; i++) { string += ' world'; }

คุณสามารถดูได้ใน Android Studio Monitors ว่าการต่อสายอักขระบางตัวไม่มีประสิทธิภาพเพียงใด มี Garbage Collections (GC) มากมายเกิดขึ้น



สตริงกับ StringBuilder

การดำเนินการนี้ใช้เวลาประมาณ 8 วินาทีบนอุปกรณ์ที่ค่อนข้างดีของฉันซึ่งมี Android 5.1.1 วิธีที่มีประสิทธิภาพมากขึ้นในการบรรลุเป้าหมายเดียวกันคือการใช้ StringBuilder เช่นนี้



StringBuilder sb = new StringBuilder('hello'); for (int i = 0; i <10000; i++) { sb.append(' world'); } String string = sb.toString();

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

String string = 'hello' + ' world';

ได้รับการแปลงภายในเป็น StringBuilder ดังนั้นจึงทำงานได้ดี



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

String myString = 'hello'; myString += ' world';

สิ่งที่คุณจะได้รับในหน่วยความจำไม่ใช่ 1 String“ hello world” แต่จริงๆแล้ว 2 Strings String myString จะมีคำว่า“ hello world” ตามที่คุณคาดหวัง อย่างไรก็ตามสตริงดั้งเดิมที่มีค่า“ สวัสดี” ยังมีชีวิตอยู่โดยไม่มีการอ้างอิงใด ๆ เพื่อรอการเก็บรวบรวมขยะ นี่คือเหตุผลที่คุณควรจัดเก็บรหัสผ่านไว้ในอาร์เรย์ถ่านแทนสตริง หากคุณจัดเก็บรหัสผ่านเป็น String รหัสผ่านจะยังคงอยู่ในหน่วยความจำในรูปแบบที่มนุษย์อ่านได้จนถึง GC ถัดไปสำหรับระยะเวลาที่คาดเดาไม่ได้ กลับไปที่ความไม่เปลี่ยนรูปที่อธิบายไว้ข้างต้น String จะยังคงอยู่ในหน่วยความจำแม้ว่าคุณจะกำหนดค่าอื่นหลังจากใช้งานแล้วก็ตาม อย่างไรก็ตามหากคุณล้างอาร์เรย์ถ่านหลังจากใช้รหัสผ่านรหัสผ่านจะหายไปจากทุกที่



2. การเลือกประเภทข้อมูลที่ถูกต้อง

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

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

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

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

@Override public int compareTo(Object object) { Meal meal = (Meal) object; if (this.timestamp meal.getTimestamp()) { return 1; } return 0; }

3. การอัปเดตตำแหน่ง

มีแอปมากมายที่รวบรวมตำแหน่งของผู้ใช้ คุณควรใช้ Google Location Services API เพื่อจุดประสงค์นั้นซึ่งมีฟังก์ชันที่มีประโยชน์มากมาย มี บทความแยกต่างหาก เกี่ยวกับการใช้งานดังนั้นฉันจะไม่พูดซ้ำ

ฉันแค่อยากเน้นประเด็นสำคัญบางอย่างจากมุมมองด้านประสิทธิภาพ

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

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

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

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

4. คำขอเครือข่าย

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

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

คำขอเครือข่าย

แล้วคุณจะทำอะไรได้บ้าง? แบทช์ เพื่อหลีกเลี่ยงการปลุกวิทยุทุกๆสองสามวินาทีให้ดึงสิ่งที่ผู้ใช้อาจต้องการไว้ล่วงหน้าในนาทีที่กำลังจะมาถึง วิธีการจัดกลุ่มที่เหมาะสมนั้นมีไดนามิกสูงขึ้นอยู่กับแอปของคุณ แต่ถ้าเป็นไปได้คุณควรดาวน์โหลดข้อมูลที่ผู้ใช้อาจต้องการในอีก 3-4 นาทีถัดไป นอกจากนี้ยังสามารถแก้ไขพารามิเตอร์แบทช์ตามประเภทอินเทอร์เน็ตของผู้ใช้หรือสถานะการชาร์จ ตัวอย่างเช่นหากผู้ใช้ใช้ WiFi ขณะชาร์จคุณสามารถดึงข้อมูลล่วงหน้าได้มากกว่าหากผู้ใช้ใช้อินเทอร์เน็ตบนมือถือโดยใช้แบตเตอรี่ต่ำ การพิจารณาตัวแปรเหล่านี้ทั้งหมดอาจเป็นเรื่องยากซึ่งมีเพียงไม่กี่คนที่จะทำได้ โชคดีที่มี GCM Network Manager คอยช่วยเหลือ!

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

Task task = new OneoffTask.Builder() .setService(CustomService.class) .setExecutionWindow(0, 30) .setTag(LogService.TAG_TASK_ONEOFF_LOG) .setUpdateCurrent(false) .setRequiredNetwork(Task.NETWORK_STATE_CONNECTED) .setRequiresCharging(false) .build();

อย่างไรก็ตามตั้งแต่ Android 3.0 หากคุณส่งคำขอเครือข่ายในเธรดหลักคุณจะได้รับ NetworkOnMainThreadException แน่นอนว่าจะเตือนคุณว่าอย่าทำแบบนั้นอีก

5. การสะท้อนกลับ

การสะท้อนกลับคือความสามารถของคลาสและอ็อบเจ็กต์ในการตรวจสอบตัวสร้างฟิลด์วิธีการและอื่น ๆ ของตนเอง โดยปกติจะใช้สำหรับความเข้ากันได้แบบย้อนหลังเพื่อตรวจสอบว่ามีวิธีการที่กำหนดสำหรับ OS เวอร์ชันใดรุ่นหนึ่งหรือไม่ หากคุณต้องใช้การสะท้อนเพื่อจุดประสงค์นั้นตรวจสอบให้แน่ใจว่าได้แคชการตอบสนองเนื่องจากการใช้การสะท้อนค่อนข้างช้า ไลบรารีที่ใช้กันอย่างแพร่หลายบางแห่งใช้ Reflection เช่นกันเช่น Roboguice สำหรับการฉีดแบบพึ่งพา นั่นคือเหตุผลที่คุณควรชอบ Dagger 2 สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการสะท้อนคุณสามารถตรวจสอบ โพสต์แยกต่างหาก .

วิธีจัดการบอทที่ไม่ลงรอยกัน

6. Autoboxing

การทำกล่องอัตโนมัติและการแกะกล่องเป็นกระบวนการในการแปลงประเภทดั้งเดิมเป็นประเภทวัตถุหรือในทางกลับกัน ในทางปฏิบัติหมายถึงการแปลง int เป็นจำนวนเต็ม เพื่อให้บรรลุนั้นคอมไพเลอร์ใช้ Integer.valueOf() ทำงานภายใน การแปลงไม่เพียง แต่ช้า แต่ Objects ยังใช้หน่วยความจำมากกว่าเดิมอีกด้วย มาดูโค้ดกัน

Integer total = 0; for (int i = 0; i <1000000; i++) { total += i; }

แม้ว่าจะใช้เวลาโดยเฉลี่ย 500 มิลลิวินาที แต่การเขียนใหม่เพื่อหลีกเลี่ยงการบ็อกซ์อัตโนมัติจะทำให้เร็วขึ้นอย่างมาก

int total = 0; for (int i = 0; i <1000000; i++) { total += i; }

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

โอเคคุณคงไม่ได้สร้างตัวแปรประเภท Integer บ่อยนัก แต่แล้วกรณีที่หลีกเลี่ยงได้ยากกว่าล่ะ? เช่นเดียวกับในแผนที่ที่คุณต้องใช้ Objects เช่น Map? ดูวิธีแก้ปัญหาที่หลายคนใช้

Map myMap = new HashMap(); for (int i = 0; i <100000; i++) { myMap.put(i, random.nextInt()); }

การแทรก ints แบบสุ่ม 100k ในแผนที่จะใช้เวลาประมาณ 250ms ในการรัน ตอนนี้ดูวิธีแก้ปัญหาด้วย SparseIntArray

SparseIntArray myArray = new SparseIntArray(); for (int i = 0; i <100000; i++) { myArray.put(i, random.nextInt()); }

ใช้เวลาน้อยกว่ามากประมาณ 50ms นอกจากนี้ยังเป็นหนึ่งในวิธีการที่ง่ายกว่าในการปรับปรุงประสิทธิภาพโดยไม่ต้องทำอะไรซับซ้อนและยังอ่านโค้ดได้อีกด้วย ในขณะที่เรียกใช้แอปที่ชัดเจนด้วยโซลูชันแรกใช้หน่วยความจำของฉัน 13MB การใช้ ints ดั้งเดิมทำให้บางอย่างต่ำกว่า 7MB ดังนั้นแค่ครึ่งเดียว

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

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

7. OnDraw

ดังที่ฉันได้กล่าวไว้ข้างต้นเมื่อคุณเพิ่มประสิทธิภาพคุณอาจเห็นประโยชน์สูงสุดในการเพิ่มประสิทธิภาพโค้ดซึ่งทำงานบ่อย หนึ่งในฟังก์ชันที่ทำงานบ่อยมากคือ onDraw() อาจไม่แปลกใจที่คุณมีหน้าที่วาดมุมมองบนหน้าจอ เนื่องจากอุปกรณ์มักจะทำงานที่ 60 fps ฟังก์ชันจะทำงาน 60 ครั้งต่อวินาที ทุกเฟรมมีเวลา 16 ms ที่ต้องจัดการอย่างเต็มที่รวมถึงการจัดเตรียมและการวาดภาพดังนั้นคุณควรหลีกเลี่ยงฟังก์ชันที่ช้า เฉพาะเธรดหลักเท่านั้นที่สามารถวาดบนหน้าจอได้ดังนั้นคุณควรหลีกเลี่ยงการดำเนินการที่มีราคาแพงกับมัน หากคุณตรึงเธรดหลักเป็นเวลาหลายวินาทีคุณอาจได้รับกล่องโต้ตอบ Application Not Responding (ANR) ที่น่าอับอาย สำหรับการปรับขนาดรูปภาพงานฐานข้อมูล ฯลฯ ให้ใช้เธรดพื้นหลัง

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

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

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

8. ViewHolders

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

static class ViewHolder { TextView title; TextView text; public ViewHolder(View view) { title = (TextView) view.findViewById(R.id.title); text = (TextView) view.findViewById(R.id.text); } }

จากนั้นภายใน getView() ฟังก์ชั่นของอะแดปเตอร์ของคุณคุณสามารถตรวจสอบว่าคุณมีมุมมองที่ใช้งานได้หรือไม่ ถ้าไม่คุณสร้างขึ้นมา

ViewHolder viewHolder; if (convertView == null) { convertView = inflater.inflate(R.layout.list_item, viewGroup, false); viewHolder = new ViewHolder(convertView); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } viewHolder.title.setText('Hello World');

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

9. การปรับขนาดรูปภาพ

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

คุณจึงมีบิตแมป แต่คุณไม่รู้อะไรเลย มีการตั้งค่าสถานะที่เป็นประโยชน์ของ Bitmaps ที่เรียกว่า inJustDecodeBounds ที่บริการของคุณซึ่งช่วยให้คุณค้นหาความละเอียดของบิตแมปได้ สมมติว่าบิตแมปของคุณคือ 1024x768 และ ImageView ที่ใช้แสดงมีขนาดเพียง 400x300 คุณควรหารความละเอียดของบิตแมปด้วย 2 ไปเรื่อย ๆ จนกว่าจะยังใหญ่กว่า ImageView ที่กำหนด ถ้าคุณทำมันจะลดขนาดบิตแมปลงด้วยปัจจัย 2 ทำให้คุณมีบิตแมป 512x384 บิตแมปแบบลดขนาดใช้หน่วยความจำน้อยลง 4 เท่าซึ่งจะช่วยคุณได้มากในการหลีกเลี่ยงข้อผิดพลาด OutOfMemory ที่มีชื่อเสียง

ตอนนี้คุณรู้วิธีทำแล้วคุณไม่ควรทำ …อย่างน้อยก็ไม่ใช่ว่าแอปของคุณต้องใช้รูปภาพเป็นหลักและไม่ใช่แค่ 1-2 ภาพ หลีกเลี่ยงสิ่งต่างๆเช่นการปรับขนาดและการรีไซเคิลภาพด้วยตนเองอย่างแน่นอนใช้ไลบรารีของบุคคลที่สามเพื่อสิ่งนั้น คนที่นิยมมากที่สุดคือ ปิกัสโซ โดย Square Universal Image Loader , เย็น โดย Facebook หรือรายการโปรดของฉัน ร่อน . มีชุมชนนักพัฒนาที่กระตือรือร้นอยู่รอบ ๆ ดังนั้นคุณสามารถค้นหาผู้คนมากมายที่เป็นประโยชน์ได้ที่หัวข้อปัญหาใน GitHub เช่นกัน

10. โหมดเข้มงวด

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

public void onCreate() { if (DEVELOPER_MODE) { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork() .penaltyLog() .build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() .detectLeakedClosableObjects() .penaltyLog() .penaltyDeath() .build()); } super.onCreate(); }

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

ประสิทธิภาพการดีบัก: วิธีระดับมืออาชีพ

ตอนนี้เรามาดูเครื่องมือบางอย่างที่สามารถช่วยคุณค้นหาปัญหาคอขวดหรืออย่างน้อยก็แสดงว่ามีบางอย่างผิดปกติ

1. Android Monitor

นี่คือเครื่องมือที่มีอยู่ใน Android Studio ตามค่าเริ่มต้นคุณจะพบ Android Monitor ที่มุมล่างซ้ายและสลับไปมาระหว่าง 2 แท็บได้ที่นั่น Logcat และจอภาพ ส่วนจอภาพประกอบด้วยกราฟ 4 แบบ เครือข่าย CPU GPU และหน่วยความจำ พวกเขาค่อนข้างอธิบายตัวเองได้ดีดังนั้นฉันจะรีบผ่านมันไป นี่คือภาพหน้าจอของกราฟที่ถ่ายขณะแยกวิเคราะห์ JSON บางส่วนเมื่อดาวน์โหลด

จอภาพ Android

ส่วนเครือข่ายจะแสดงการรับส่งข้อมูลขาเข้าและขาออกในหน่วย KB / s ส่วนของ CPU จะแสดงการใช้งาน CPU เป็นเปอร์เซ็นต์ จอภาพ GPU จะแสดงระยะเวลาที่ใช้ในการแสดงผลเฟรมของหน้าต่าง UI นี่คือจอภาพที่มีรายละเอียดมากที่สุดจาก 4 ตัวนี้ดังนั้นหากคุณต้องการรายละเอียดเพิ่มเติม อ่านนี่ .

สุดท้ายนี้เรามีไฟล์ จอภาพหน่วยความจำ ซึ่งคุณอาจใช้มากที่สุด ตามค่าเริ่มต้นจะแสดงจำนวนหน่วยความจำที่ว่างและจัดสรรในปัจจุบัน คุณสามารถบังคับใช้ Garbage Collection ได้เช่นกันเพื่อทดสอบว่าจำนวนหน่วยความจำที่ใช้ลดลงหรือไม่ มีคุณสมบัติที่มีประโยชน์ที่เรียกว่า Dump Java Heap ซึ่งจะสร้างไฟล์ HPROF ซึ่งสามารถเปิดได้ด้วยไฟล์ HPROF Viewer และ Analyzer . ซึ่งจะช่วยให้คุณเห็นจำนวนวัตถุที่คุณจัดสรรหน่วยความจำถูกยึดไปเท่าใดและวัตถุใดที่ทำให้หน่วยความจำรั่วไหล การเรียนรู้วิธีใช้เครื่องวิเคราะห์นี้ไม่ใช่งานที่ง่ายที่สุด แต่ก็คุ้มค่า สิ่งต่อไปที่คุณสามารถทำได้กับ Memory Monitor คือทำการติดตามการจัดสรรตามกำหนดเวลาซึ่งคุณสามารถเริ่มและหยุดได้ตามที่คุณต้องการ อาจมีประโยชน์ในหลาย ๆ กรณีตัวอย่างเช่นเมื่อเลื่อนหรือหมุนอุปกรณ์

2. GPU Overdraw

นี่เป็นเครื่องมือตัวช่วยง่ายๆซึ่งคุณสามารถเปิดใช้งานได้ในตัวเลือกสำหรับนักพัฒนาเมื่อคุณเปิดใช้งานโหมดนักพัฒนาแล้ว เลือก Debug GPU overdraw,“ Show overdraw areas” และหน้าจอของคุณจะมีสีแปลก ๆ โอเคนั่นคือสิ่งที่ควรจะเกิดขึ้น สีหมายถึงจำนวนครั้งที่พื้นที่หนึ่ง ๆ ถูกวาดทับ สีที่แท้จริงหมายความว่าไม่มีการวาดทับนี่คือสิ่งที่คุณควรตั้งเป้าหมาย สีน้ำเงินหมายถึงการวางทับหนึ่งครั้งสีเขียวหมายถึงสองสีชมพูสามสีแดงสี่

GPU Overdraw

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

3. การแสดงผล GPU

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

การแสดงผล GPU

แถบประกอบด้วยสี 3-4 สีและตามเอกสารของ Android ขนาดของมันมีความสำคัญอย่างยิ่ง ยิ่งเล็กยิ่งดี ที่ด้านล่างคุณจะมีสีน้ำเงินซึ่งแสดงถึงเวลาที่ใช้ในการสร้างและอัปเดตรายการที่แสดงของ View หากส่วนนี้สูงเกินไปแสดงว่ามีมุมมองแบบกำหนดเองจำนวนมากหรือมีงานจำนวนมากที่ทำใน onDraw() ฟังก์ชั่น. หากคุณมี Android 4.0+ คุณจะเห็นแถบสีม่วงเหนือแถบสีน้ำเงิน นี่แสดงถึงเวลาที่ใช้ในการถ่ายโอนทรัพยากรไปยังเธรดการแสดงผล จากนั้นก็มาถึงส่วนสีแดงซึ่งแสดงถึงเวลาที่ใช้ในการแสดงผล 2D ของ Android ที่ออกคำสั่งไปยัง OpenGL เพื่อวาดและวาดใหม่รายการที่แสดง ที่ด้านบนคือแถบสีส้มซึ่งแสดงถึงเวลาที่ CPU กำลังรอให้ GPU ทำงานให้เสร็จสิ้น หากสูงเกินไปแสดงว่าแอปทำงานกับ GPU มากเกินไป

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

4. ผู้ดูลำดับชั้น

นี่เป็นหนึ่งในเครื่องมือโปรดของฉันเนื่องจากมีประสิทธิภาพมาก คุณสามารถเริ่มได้จาก Android Studio ผ่าน Tools -> Android -> Android Device Monitor หรือจะอยู่ในโฟลเดอร์ sdk / tools ของคุณเป็น 'จอภาพ' ก็ได้ นอกจากนี้คุณยังสามารถค้นหา hierarachyviewer แบบสแตนด์อโลนที่ปฏิบัติการได้ที่นั่น แต่เมื่อเลิกใช้แล้วคุณควรเปิดจอภาพ อย่างไรก็ตามคุณเปิดการตรวจสอบอุปกรณ์ Android ให้เปลี่ยนไปใช้มุมมองของผู้ดูลำดับชั้น หากคุณไม่เห็นแอปที่ทำงานอยู่ที่กำหนดให้กับอุปกรณ์ของคุณ นั่นเอง มีสองสิ่งที่คุณสามารถทำได้เพื่อแก้ไข ลองตรวจสอบดู นี้ เธรดปัญหามีผู้ที่มีปัญหาทุกประเภทและวิธีแก้ปัญหาทุกประเภท บางอย่างก็น่าจะเหมาะกับคุณเช่นกัน

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

หลีกเลี่ยงการเรียก requestLayout() เนื่องจากจะทำให้เกิดการข้ามลำดับชั้นการดูทั้งหมดเพื่อดูว่าแต่ละมุมมองควรมีขนาดใหญ่เพียงใด หากมีข้อขัดแย้งกับการวัดลำดับชั้นอาจมีการข้ามหลายครั้งซึ่งหากเกิดขึ้นในระหว่างการเคลื่อนไหวบางอย่างจะทำให้บางเฟรมถูกข้ามไปอย่างแน่นอน หากคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับวิธีที่ Android ดึงมุมมองคุณสามารถทำได้ อ่านนี่ . มาดูมุมมองเดียวที่เห็นใน Hierarchy Viewer

ผู้ดูลำดับชั้น

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

ภายใต้ค่าที่คุณมีชื่อคลาสเช่น 'TextView', ID มุมมองภายในของออบเจ็กต์และ android: id ของมุมมองซึ่งคุณตั้งไว้ในไฟล์ XML ฉันขอแนะนำให้คุณสร้างนิสัยในการเพิ่ม ID ให้กับทุกมุมมองแม้ว่าคุณจะไม่ได้อ้างอิงในโค้ดก็ตาม จะทำให้การระบุมุมมองใน Hierarchy Viewer เป็นเรื่องง่ายมากและในกรณีที่คุณมีการทดสอบอัตโนมัติในโครงการของคุณก็จะทำให้การกำหนดเป้าหมายองค์ประกอบเร็วขึ้นมาก ซึ่งจะช่วยประหยัดเวลาสำหรับคุณและเพื่อนร่วมงานของคุณในการเขียน การเพิ่ม ID ให้กับองค์ประกอบที่เพิ่มในไฟล์ XML นั้นค่อนข้างตรงไปตรงมา แต่องค์ประกอบที่เพิ่มแบบไดนามิกล่ะ? มันก็ดูเรียบง่ายเหมือนกัน เพียงสร้างไฟล์ ids.xml ภายในโฟลเดอร์ค่าของคุณและพิมพ์ในฟิลด์ที่จำเป็น จะมีลักษณะดังนี้:

setId(R.id.item_title)

จากนั้นในโค้ดคุณสามารถใช้ LinearLayouts มันไม่ง่ายไปกว่านี้แล้ว

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

|_+_|
. ลองสร้างมุมมองที่กำหนดเองบางส่วนเมื่อจำเป็นซึ่งสามารถปรับปรุงประสิทธิภาพได้อย่างมากหากทำได้ดี ตัวอย่างเช่นคุณทราบหรือไม่ว่า Instagram ไม่ได้ใช้ TextView สำหรับ การแสดงความคิดเห็น เหรอ?

คุณสามารถค้นหาข้อมูลเพิ่มเติมเกี่ยวกับ Hierarchy Viewer ได้ที่ ไซต์ Android Developers พร้อมคำอธิบายของบานหน้าต่างที่แตกต่างกันโดยใช้เครื่องมือ Pixel Perfect เป็นต้นอีกสิ่งหนึ่งที่ฉันอยากจะชี้ให้เห็นคือการจับภาพมุมมองในไฟล์. psd ซึ่งทำได้โดยปุ่ม“ จับภาพเลเยอร์หน้าต่าง” ทุกมุมมองจะอยู่ในเลเยอร์ที่แยกจากกันดังนั้นจึงง่ายมากที่จะซ่อนหรือเปลี่ยนแปลงใน Photoshop หรือ GIMP นั่นเป็นอีกเหตุผลหนึ่งในการเพิ่ม ID ในทุกมุมมองที่คุณทำได้ มันจะทำให้เลเยอร์มีชื่อที่สมเหตุสมผล

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

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

ห่อ

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

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

ออกแบบเวิร์กโฟลว์สำหรับนักพัฒนา: การส่งมอบ UX / UI ที่ดีขึ้นในเวลาและรูปแบบ

ไลฟ์สไตล์

ออกแบบเวิร์กโฟลว์สำหรับนักพัฒนา: การส่งมอบ UX / UI ที่ดีขึ้นในเวลาและรูปแบบ
ApeeScape Design Blog สีสันแห่งปี 2020

ApeeScape Design Blog สีสันแห่งปี 2020

การออกแบบ Ux

โพสต์ยอดนิยม
ตายไปยัง Wireframes มุ่งตรงสู่ความเที่ยงตรงสูง!
ตายไปยัง Wireframes มุ่งตรงสู่ความเที่ยงตรงสูง!
React Components ทำให้การทดสอบ UI เป็นเรื่องง่ายได้อย่างไร
React Components ทำให้การทดสอบ UI เป็นเรื่องง่ายได้อย่างไร
คำแนะนำขั้นสุดท้ายสำหรับฐานข้อมูล NoSQL
คำแนะนำขั้นสุดท้ายสำหรับฐานข้อมูล NoSQL
ในฐานะนักพัฒนา JS นี่คือสิ่งที่ทำให้ฉันตื่นขึ้นมาในเวลากลางคืน
ในฐานะนักพัฒนา JS นี่คือสิ่งที่ทำให้ฉันตื่นขึ้นมาในเวลากลางคืน
การติดตั้ง Remote Framebuffer Server ใน Java
การติดตั้ง Remote Framebuffer Server ใน Java
 
การทำงานระยะไกลและการบริการระดับโลก
การทำงานระยะไกลและการบริการระดับโลก
ApeeScape Global Mentors: การศึกษาทุกที่
ApeeScape Global Mentors: การศึกษาทุกที่
การออกแบบ VUI - Voice User Interface
การออกแบบ VUI - Voice User Interface
การพัฒนาแอปพลิเคชันด้วย Rapid Application Development Framework AllcountJS
การพัฒนาแอปพลิเคชันด้วย Rapid Application Development Framework AllcountJS
เศรษฐีใหม่: การสร้างอาชีพอิสระที่ร่ำรวย
เศรษฐีใหม่: การสร้างอาชีพอิสระที่ร่ำรวย
โพสต์ยอดนิยม
  • cac ในด้านการเงินคืออะไร
  • สถานที่ที่ดีที่สุดในการเรียนรู้ c++
  • google dorks สำหรับบัตรเครดิต
  • หลักการเกสตัลต์ข้อใดระบุว่าเรามักจะรับรู้วัตถุเป็นกลุ่ม
  • ซึ่งเป็นแนวปฏิบัติที่ดีในการออกแบบแอพ
  • วิธีการออกแบบต้นแบบ
หมวดหมู่
  • นักลงทุนและเงินทุน
  • ทีมแบบกระจาย
  • เทคโนโลยี
  • แนวโน้ม
  • © 2022 | สงวนลิขสิทธิ์

    portaldacalheta.pt