Tối ưu hóa ứng dụng Android trước khi phát hành [đóng cửa]


120

Tôi đang ở trong một tình huống " đặc biệt " về hiệu quả của chương trình của tôi. Bây giờ tôi đang ở giai đoạn mà tôi cần cải thiện hiệu suất của ứng dụng và giảm mức tiêu thụ pin .

Trước câu hỏi:

Bây giờ, tôi tò mò muốn biết về các bản sửa lỗi đặc biệt của các nhà phát triển khác mà họ đã sử dụng để tối ưu hóa ứng dụng của riêng họ. Nội dung mà người dùng có thể không bao giờ nhận ra hoặc chú ý đến. Tuy nhiên, các bản sửa lỗi sẽ tăng tuổi thọ pin hoặc giúp cải thiện khả năng bảo trì ứng dụng.

Vậy, (các) thủ thuật tối ưu hóa độc đáo của bạn là gì?

Tôi đang ở trong một tình huống cụ thể mà tôi thực sự đang tìm kiếm kiến ​​thức và tôi nghĩ đây sẽ là cơ hội tuyệt vời để chia sẻ kiến ​​thức của các nhà phát triển về tình huống mà tất cả họ đã từng gặp phải.

Vui lòng bình chọn những câu trả lời tuyệt vời vì điều đó sẽ khuyến khích các nhà phát triển tuyệt vời chia sẻ kiến ​​thức của họ.


2
Vì hiệu quả cuối cùng đi đến việc không làm bất cứ điều gì bạn không cần (hoặc thường xuyên hơn bạn cần), tôi sẽ nghĩ rằng rất nhiều điều sẽ phụ thuộc vào loại công việc mà ứng dụng của bạn phải hoàn thành ... Không chỉ rõ điều đó, tất cả các bạn có thể làm là có được một bộ sưu tập các "nghi phạm thông thường"
Chris Stratton

1
@Chris Stratton: Chà, bạn nói đúng. Nhưng cũng có thể, "nghi phạm thông thường" hoặc một câu trả lời nhỏ về một thủ thuật cụ thể sẽ giúp người khác dễ dàng đưa ra quyết định hơn nếu "phỏng đoán" đó là thứ họ đang tìm kiếm (và nếu nó hữu ích cho tình huống cụ thể của họ).
Wroclai

Thật nực cười khi có bao nhiêu câu hỏi thực sự thú vị được đóng lại trên trang web này.
Patrick

Câu trả lời:


68

Tại một thời điểm nào đó, bạn sẽ đạt đến điểm mà việc sử dụng các thủ thuật đã biết sẽ đạt đến giới hạn của chúng. Điều tốt nhất cần làm lúc này là lập hồ sơ mã của bạn và xem những lĩnh vực nào là cổ chai dựa trên yêu cầu cụ thể của bạn.

Điều tra việc sử dụng RAM bằng MATSử dụng Traceview : bài viết về cách sử dụng các công cụ để lập hồ sơ ứng dụng của bạn.


Cảm ơn! Tôi thực sự thích câu trả lời với các nguồn. :-)
Wroclai

1
Đọc bài đăng trên blog này. medium.com/@hammad_tariq/…
Developine

37

Theo dõi và phân bổ bí. Bạn càng phân bổ nhiều, trình thu gom rác sẽ cần chạy thường xuyên hơn, ngăn quá trình của bạn làm bất kỳ điều gì khác trong khoảng thời gian tương đối dài, chẳng hạn như 100ms hoặc lâu hơn.

Công cụ tốt nhất mà tôi biết cho việc này là Trình theo dõi phân bổ có trong DDMS .

Không chỉ GC có thể có tác động đến trải nghiệm người dùng, mà các phân bổ thừa và GC cũng tiêu tốn một số tài nguyên máy tính.

Đây là một ví dụ và một thủ thuật nhỏ. Trong ứng dụng của tôi, tôi có đồng hồ hiển thị thời gian (âm thanh) hiện tại, bao gồm cả phần mười giây. Điều này được cập nhật thường xuyên. Và TextView thực hiện phân bổ nội bộ bất cứ khi nào bạn gọi setText () với CharSequence. Nhưng nó không phân bổ bất kỳ thứ gì với biến thể setText (char [] text, int start, int len). Điều này không được ghi lại, và không ai trả lời khi tôi hỏi về nó.

Có rất nhiều cái như thế này. Và đây là một trong những lý do tại sao ứng dụng của tôi chứa 50% mã gốc (nhưng còn những lý do khác).

Ngoài ra, tôi có thể khuyên bạn nên thử nghiệm với ProGuard . Nó thực hiện một số lần tối ưu hóa và ghi lại các thông tin như các phương pháp không sử dụng trong dự án, có thể giúp bạn loại bỏ phần thừa trong mã của mình.


1
Câu trả lời chính xác! Thủ thuật bê tông được đánh giá cao.
Wroclai

22

Nếu ứng dụng của bạn có nhiều thời gian sử dụng màn hình, hãy sử dụng màu đen ở bất kỳ đâu bạn có thể . Điều đó sẽ làm giảm mức tiêu thụ pin của phần tồi tệ nhất của thiết bị: màn hình, đặc biệt là trong điện thoại và máy tính bảng AMOLED.


Sử dụng hợp lý các màu tối có nghĩa là một chiến thắng cho pin.
Robert Massaioli

7
Mặt khác, màu đen thu hút nhiều điện năng hơn màu trắng trên màn hình LCD, bởi vì ánh sáng (lấy từ đèn nền) bắt đầu có màu trắng và phải bị chặn tích cực để tạo ra màu đen. [ Scientificamerican.com/article.cfm?id=fact-or-fiction-black-is ] Điểm mấu chốt: Đừng quá tin tưởng vào việc tối ưu hóa màu sắc này.
Sparky

16

Đối với các ứng dụng có nhiều hoạt động, hãy kiểm tra xem bạn có đang khởi động lại các hoạt động chỉ cần đưa lên trước bằng cách sử dụng cờ Ý định thích hợp. Kiểm tra xem heap của bạn có được kiểm soát không và các chế độ xem, liên kết và ngữ cảnh không cần thiết không được tạo.

Tôi thấy công cụ tốt nhất để hiển thị cho bạn tất cả những điều này khi ứng dụng chạy là:

adb shell dumpsys meminfo 'your apps package name'

1
Ồ, đó là mới. Cám ơn vì đã chia sẻ!
Wroclai

15

Khi sử dụng SQLlite, hãy đặc biệt chú ý đến các chỉ mục. Đừng giả định bất cứ điều gì. Tôi đã nhận được tốc độ đáng kể trong Zwitscher, khi tôi đặt chỉ mục trên các cột thường được sử dụng để tìm kiếm.


13

Một số mẹo có thể giúp bạn tối ưu hóa ứng dụng của mình về giao diện người dùng :

  • sử dụng convertViewcho bộ điều hợp danh sách - sẽ rất tốn kém nếu bạn tạo một dạng xem mới bên trong Adapter.getView()vì quy trình này được gọi cho mọi vị trí trong danh sách. Việc sử dụng convertViewcho phép bạn sử dụng lại chế độ xem đã được tạo. Ví dụ tốt (cùng với việc sử dụng ViewHolder) có thể được tìm thấy trong ApiDemos .

  • Có thể xảy ra trường hợp bố cục của bạn không được tối ưu hóa hoàn toàn và có thể được cải thiện (ví dụ: bằng cách sử dụng hợp nhất hoặc xóa cha mẹ). Bố cục công cụ Android sẽ tìm ra tình huống như vậy cho bạn. Nó có thể được sử dụng với HierarchyViewer để kiểm tra các chế độ xem riêng lẻ. Thêm thông tin ở đây .

  • loại bỏ nền có thể vẽ được - Android framework từng gặp vấn đề với việc phát hiện khung nhìn nào nên được vẽ. Có khả năng là nền (mặc định) có thể vẽ của bạn sẽ chỉ được vẽ để sau đó bị ẩn bởi giao diện người dùng mờ đục của bạn. Để loại bỏ bản vẽ lãng phí này, chỉ cần xóa nền có thể vẽ được.

Nó có thể được thực hiện bằng cách sử dụng một phong cách tùy chỉnh

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

Một số mẹo có thể giúp bạn tối ưu hóa ứng dụng của mình về mức sử dụng pin :

  • kiểm tra loại mạng và đợi cho đến khi người dùng ở trong khu vực có wifi hoặc 3G (và không chuyển vùng) rồi chỉ cho phép họ sử dụng kết nối

  • sử dụng gzip cho dữ liệu văn bản bất cứ khi nào có thể để tăng tốc tải xuống và phân tích cú pháp

  • tái chế các đối tượng java phức tạp như XmlPullParserFactory/ BitmapFactory/ StringBuilder/ Matcherv.v.

Để biết thêm các thủ thuật về pin, hãy xem Mã hóa cho Tuổi thọ - Pin, Tức là .


"tái chế các đối tượng java phức tạp như vậy ..." Làm thế nào? trong khi Java có GC
Yousha Aleayoub

9

Điều cần suy nghĩ: KHÔNG lạm dụng Chuỗi, ví dụ như trong một vòng lặp lớn. Điều này sẽ tạo ra rất nhiều đối tượng Chuỗi phải được GC'ed. Ví dụ "Mã hóa sai" sẽ tạo ra 2 đối tượng chuỗi mỗi vòng lặp. Ví dụ tiếp theo sẽ chỉ tạo ra một chuỗi cuối cùng và một trình tạo chuỗi duy nhất. Điều này tạo ra sự khác biệt rất lớn khi tối ưu hóa các vòng lặp lớn cho tốc độ. Tôi đã sử dụng stringbuilder rất nhiều khi tạo ứng dụng Wordlist Pro Android của mình và nó thực sự nhanh chóng khi lướt qua 270000 từ ngay lập tức.

    //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);
    }

Tôi đã viết một bài đăng blog mở rộng hơn về vấn đề này. đọc ở đây


6

Tôi đoán việc sử dụng các biến "cuối cùng" ở mọi nơi có thể cũng có thể cải thiện tốc độ thực thi.


1
Tôi nhớ đã đọc ở đâu đó, bạn có thể cung cấp một liên kết?
Wesley Wiser

1
Không phải như vậy chắc chắn đó là sự thật cho các biến cuối cùng, nhưng có thể cho các biến thức tĩnh - xem stackoverflow.com/questions/3117770/...
Alistair Collins

Không thể cung cấp liên kết nhưng tôi đã gặp một thông báo về nó trong "Hướng dẫn cho người mới bắt đầu sử dụng android" của Reto Meier (ngày 19 tháng 5 năm 2010) / Google IO. Nó ngắn gọn, tải xuống miễn phí và có nhiều lời khuyên tốt về cách xây dựng một ứng dụng tốt.
Stan

2
Các biến cuối cùng có thể làm cho mã hiệu quả hơn vì nó có nghĩa là tất cả các đối tượng sẽ được GC trong cùng một lần chạy. Không phải tại các thời điểm khác nhau dựa trên thời điểm bạn đặt chúng thành null.
Robert Massaioli

1
Câu hỏi: Trình biên dịch không làm điều đó một cách rõ ràng cho bạn? Tôi nghĩ rằng nó nên làm điều đó trong giai đoạn phân tích mã của nó.
Pawan

6

Tối ưu hóa ảnh PNG của bạn bằng các công cụ như OptiPNGPNGCrush để loại bỏ một số byte (kilo) so với kích thước APK. Các mẹo tối ưu hóa hình ảnh cho các trang web cũng được áp dụng ở đây: sử dụng các định dạng hình ảnh thích hợp, chơi với nén JPG, cân nhắc sử dụng trong suốt nhị phân thay vì trong suốt 8 bit, v.v.

Nếu bạn gửi PNG lớn với alpha kênh, bạn có thể giao dịch một số kích thước APK cho tốc độ khởi động và sử dụng JPG riêng biệt cho RGB và A kênh .

Nếu bạn đang tạo kết nối HTTP, hãy kiểm tra xem ứng dụng HTTP của bạn có sử dụng tính năng nén nội dung hay không. Nếu nó lưu vào bộ nhớ đệm đã nhận được phản hồi HTTP, hãy kiểm tra xem nó có hiểu và sử dụng đúng các tiêu đề HTTP liên quan đến bộ nhớ đệm hay không.


Cảm ơn cho cái nhìn sâu sắc! Tôi chưa bao giờ nghe nói về điều này!
Wroclai

5

Nếu bạn có hoạt động mạng, hãy thử sử dụng lại cùng một phiên bản httpclient. Tránh sử dụng cụm từ thông dụng.


Lý do? bạn có thể giải thích lý do tại sao?
Yousha Aleayoub

5

Hãy thử sử dụng DDMS để theo dõi tất cả các luồng đang chạy trong hệ thống. Ví dụ: tôi đã nhận thấy rằng tôi đang sử dụng webview để hiển thị nội dung html, tôi nhận thấy rằng nó tạo ra một số chủ đề để quản lý phiên quản lý cookie, v.v. điều đó đã làm tăng bộ nhớ của tôi. Vì vậy, trừ khi bạn có nhu cầu nghiêm túc về việc hiển thị html phức tạp, hãy thử sử dụng lớp tiện ích bình thường "Html" trong android để hiển thị nội dung html. Điều này có thể hữu ích cho những người đang hiển thị Eula vì eula typicall chứa văn bản html.

Nếu bạn phải thực hiện các hoạt động mạng, hãy thử sử dụng AndroidHttpClient nếu bạn là người mới bắt đầu, nó có một số khả năng tốt cho các phiên SSL vào bộ đệm và tất cả những gì nó thực sự giúp cải thiện hiệu suất của bạn. Luôn đặt thời gian chờ kết nối socket của bạn thành khoảng 60 giây hoặc một số giá trị hữu hạn vì thời gian chờ vô hạn có thể gây ra bế tắc, đặc biệt nếu bạn làm rơi kết nối của mình trong quá trình bắt tay ssl.



4

Tránh sử dụng XPath nếu bạn có thể phân tích cú pháp đầu vào XML của mình bằng cách sử dụng các quy trình thao tác chuỗi để lấy văn bản giữa các thẻ. Tôi đã thử nghiệm và có thể xác nhận sự cải thiện gấp 10 lần trong trường hợp này, trên tập dữ liệu 50000 mục, trên HTC Desire.


3

Tôi biết tôi sẽ tham gia cuộc trò chuyện này muộn hơn một chút nhưng sẽ thật hoàn hảo nếu có nhiều mẹo hay ở một nơi, vì vậy tôi hy vọng chủ đề này sẽ tồn tại và được cập nhật thường xuyên. Mẹo của tôi:

  • Đừng chặn chuỗi giao diện người dùng với các công việc đắt tiền, người dùng sẽ rời đi nếu không có phản hồi từ ứng dụng (sử dụng AsyncThreads).
  • Sử dụng LINT , công cụ mới quét các nguồn dự án Android để tìm các lỗi tiềm ẩn.

..sẽ tiếp tục cập nhật..

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.