การเพิ่มประสิทธิภาพแอปพลิเคชัน Android ก่อนเปิดตัว [ปิด]


120

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

ก่อนคำถาม:

  • ก่อนอื่นใบสมัครของฉันได้ผล มันทำงานได้ดี - ไม่มีข้อผิดพลาดใด ๆ
  • ประการที่สองฉันได้อ่านOptimizing Battery Life บนเว็บไซต์นักพัฒนา Androidและฉันได้เพิ่มประสิทธิภาพสิ่งเล็ก ๆ ที่พวกเขาร้องขอ ไม่มีปัญหาใด ๆ

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

ดังนั้นสิ่งที่เพิ่มประสิทธิภาพเคล็ดลับเฉพาะของคุณ (s)?

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

โปรดโหวตคำตอบที่ยอดเยี่ยมเพราะจะกระตุ้นให้นักพัฒนาที่ยอดเยี่ยมแบ่งปันความรู้ของพวกเขา


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

1
@ Chris Stratton: คุณพูดถูก แต่นอกจากนี้ "ผู้ต้องสงสัยตามปกติ" หรือคำตอบเล็ก ๆ น้อย ๆ เกี่ยวกับเคล็ดลับเฉพาะจะช่วยให้ผู้อื่นตัดสินใจได้ง่ายขึ้นว่า "การคาดเดา" นั้นคือสิ่งที่พวกเขากำลังมองหาหรือไม่ (และหากเป็นประโยชน์สำหรับสถานการณ์เฉพาะของพวกเขา)
Wroclai

น่าขันที่มีคำถามที่น่าสนใจจริงๆถูกปิดลงบนเว็บไซต์นี้
Patrick

อ่าน blogpost medium.com/@hammad_tariq/…
Developine

คำตอบ:


68

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

การตรวจสอบการใช้ RAM โดยใช้ MATและการใช้ Traceview : บทความเกี่ยวกับวิธีใช้เครื่องมือเพื่อกำหนดโปรไฟล์แอปพลิเคชันของคุณ


ขอบคุณ! ฉันชอบคำตอบที่มีแหล่งข้อมูลมาก :-)
Wroclai

1
อ่านบล็อกโพสต์นี้ medium.com/@hammad_tariq/…
Developine

37

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

เครื่องมือที่ดีที่สุดฉันรู้ว่านี้คือการจัดสรรติดตามรวมอยู่ในDDMS

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

นี่คือตัวอย่างและเคล็ดลับเล็ก ๆ ในแอปของฉันฉันมีนาฬิกาที่แสดงเวลาปัจจุบัน (เสียง) รวมถึงวินาทีที่สิบ มีการอัปเดตบ่อยครั้ง และ TextView ทำการจัดสรรภายในเมื่อใดก็ตามที่คุณเรียกใช้ setText () ด้วย CharSequence แต่จะไม่จัดสรรอะไรกับตัวแปร setText (char [], int start, int len) นี่ไม่ได้บันทึกไว้และไม่มีใครตอบเมื่อฉันถามเกี่ยวกับเรื่องนี้

มีหลายตัวแบบนี้ และนี่เป็นสาเหตุหนึ่งที่ทำให้แอปของฉันมีโค้ดเนทีฟ 50% (แต่มีเหตุผลอื่น ๆ )

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


1
ตอบโจทย์มาก! เทคนิคที่เป็นรูปธรรมได้รับการชื่นชม
Wroclai

22

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


การใช้สีเข้มอย่างรอบคอบหมายถึงการชนะแบตเตอรี่
Robert Massaioli

7
ในทางกลับกันสีดำจะดึงพลังงานมากกว่าสีขาวบนหน้าจอ LCD เนื่องจากแสง (ที่มาจากแสงด้านหลัง) เริ่มเป็นสีขาวและต้องถูกปิดกั้นอย่างแข็งขันเพื่อให้เกิดสีดำ [ Scientamerican.com/article.cfm?id=fact-or-fiction-black-is ] บรรทัดล่าง: อย่านับการปรับสีให้เหมาะสมมากเกินไป
Sparky

16

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

ฉันพบเครื่องมือที่ดีที่สุดในการแสดงสิ่งเหล่านี้ให้คุณเห็นเมื่อแอปทำงานคือ:

adb shell dumpsys meminfo 'your apps package name'

1
โอ้นั่นเป็นเรื่องใหม่ ขอบคุณสำหรับการแบ่งปัน!
Wroclai

15

เมื่อใช้ SQLlite ให้ความสนใจเป็นพิเศษกับดัชนี อย่าถือว่าอะไรเลย ฉันได้รับ speedups อย่างมากใน Zwitscher เมื่อฉันใส่ดัชนีในคอลัมน์ที่มักใช้สำหรับการค้นหา


13

เคล็ดลับบางประการที่สามารถช่วยคุณเพิ่มประสิทธิภาพแอปของคุณในแง่ของUI :

  • ใช้convertViewสำหรับรายการอะแดปเตอร์ - จะมีราคาแพงมากหากคุณสร้างมุมมองใหม่ภายในAdapter.getView()เนื่องจากรูทีนนี้ถูกเรียกใช้สำหรับทุกตำแหน่งในรายการ การใช้convertViewช่วยให้คุณสามารถใช้มุมมองที่สร้างไว้แล้วซ้ำได้ ตัวอย่างที่ดี (ร่วมกับการใช้งานของViewHolder) สามารถพบได้ในApiDemos

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

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

สามารถทำได้โดยใช้สไตล์ที่กำหนดเอง

<resources>
    <style name="Theme.NoBackground" parent="android:Theme">
        <item name="android:windowBackground">@null</item>
    </style>
</resources>

เคล็ดลับบางประการที่สามารถช่วยคุณเพิ่มประสิทธิภาพแอปของคุณในแง่ของการใช้งานแบตเตอรี่ :

  • ตรวจสอบประเภทเครือข่ายและรอจนกว่าผู้ใช้จะเข้ามาในพื้นที่ด้วย wifi หรือ 3G (และไม่โรมมิ่ง) จากนั้นจึงอนุญาตให้ใช้การเชื่อมต่อ

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

  • รีไซเคิลวัตถุ java ที่ซับซ้อนเช่นXmlPullParserFactory/ BitmapFactory/ StringBuilder/ Matcherฯลฯ

สำหรับเทคนิคแบตเตอรี่เพิ่มเติมโปรดดูที่การเข้ารหัสเพื่อชีวิต - แบตเตอรี่ที่เป็น


"รีไซเคิลวัตถุ java ที่ซับซ้อนเช่น ... " อย่างไร? ในขณะที่ Java มี GC
Yousha Aleayoub

9

สิ่งที่ต้องคิด: อย่าใช้ String มากเกินไปเช่นในวงขนาดใหญ่ สิ่งนี้จะสร้างออบเจ็กต์ String จำนวนมากที่ต้องมี GC'ed ตัวอย่าง "การเข้ารหัสไม่ถูกต้อง" จะสร้างออบเจ็กต์สตริง 2 รายการในทุกๆลูป ตัวอย่างถัดไปจะสร้างสตริงสุดท้ายและตัวสร้างสตริงเดียวเท่านั้น สิ่งนี้สร้างความแตกต่างอย่างมากเมื่อเพิ่มประสิทธิภาพลูปขนาดใหญ่เพื่อความเร็ว ฉันใช้ stringbuilder บ่อยมากในการสร้างแอพ Wordlist Pro สำหรับ Android และมันก็เร็วมากเมื่อต้องอ่าน 270000 คำในเวลาไม่นาน

    //Bad coding:
    String s = "";
    for(int i=0;i<999999;i++){
        s = "Number=";
        s = s + i;
        System.out.println(s);
    }

    //Better coding
    final String txt = "Number=";
    StringBuilder sb = new StringBuilder();
    for(int i=0;i < 999999;i++){
        sb.setLength(0);
        sb.append(txt);
        sb.append(i);
        System.out.println(sb);
    }

ฉันเขียนบล็อกโพสต์เพิ่มเติมเกี่ยวกับเรื่องนี้ อ่านที่นี่


6

ฉันเดาว่าการใช้ตัวแปร "สุดท้าย" ทุกที่ที่เป็นไปได้ก็สามารถปรับปรุงความเร็วในการดำเนินการได้เช่นกัน


1
ฉันจำได้ว่าอ่านที่ไหนสักแห่งช่วยให้ลิงค์ได้ไหม
เวสลีย์ไวเซอร์

1
ไม่แน่ใจว่าเป็นจริงสำหรับตัวแปรสุดท้าย แต่สามารถเป็นตัวแปรสุดท้ายแบบคงที่ได้ - ดูstackoverflow.com/questions/3117770/…
Alistair Collins

ไม่สามารถให้ลิงค์ได้ แต่ฉันพบประกาศเกี่ยวกับเรื่องนี้ใน "Beginners guide to android" โดย Reto Meier (19 พฤษภาคม 2010) / Google IO มันสั้นดาวน์โหลดได้ฟรีและมีคำแนะนำที่ดีในการสร้างแอพที่ดี
สแตน

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

1
คำถาม: คอมไพเลอร์ไม่ได้ทำเพื่อคุณอย่างชัดเจนใช่หรือไม่? ฉันคิดว่าควรทำในขั้นตอนการวิเคราะห์โค้ด
Pawan

6

ปรับแต่งรูปภาพ PNG ของคุณให้เหมาะสมด้วยเครื่องมือเช่นOptiPNGและPNGCrushเพื่อลดขนาด (กิโล) ไบต์ออกจากขนาด APK เคล็ดลับการปรับแต่งรูปภาพสำหรับเว็บไซต์ก็ใช้ได้เช่นกัน: ใช้รูปแบบภาพที่เหมาะสมเล่นด้วยการบีบอัด JPG ลองใช้แผ่นใสไบนารีแทนแผ่นใส 8 บิตเป็นต้น

หากคุณจัดส่ง PNG ขนาดใหญ่พร้อมช่องอัลฟาคุณสามารถแลกเปลี่ยนขนาด APK บางขนาดเพื่อความเร็วในการเริ่มต้นและใช้ JPG แยกกันสำหรับช่อง RGB และ Aแยกต่างหากสำหรับช่อง

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


ขอบคุณสำหรับข้อมูลเชิงลึก! ฉันไม่เคยได้ยินเรื่องนี้มาก่อน!
Wroclai

5

หากคุณมีการทำงานของเครือข่ายให้ลองใช้อินสแตนซ์ httpclient เดิมอีกครั้ง หลีกเลี่ยงการใช้นิพจน์ทั่วไป


เหตุผล? คุณอธิบายได้ไหมว่าทำไม
Yousha Aleayoub

5

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

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



4

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


3

ฉันรู้ว่าฉันกำลังเข้าร่วมการสนทนานี้ในภายหลัง แต่มันจะเป็นการดีที่จะมีเคล็ดลับดีๆมากมายในที่เดียวดังนั้นฉันหวังว่ากระทู้นี้จะยังมีชีวิตอยู่และมีการอัปเดตบ่อยๆ เคล็ดลับของฉัน:

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

.. จะปรับปรุง ..

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.