Build for Billion - Android.

Xin chào tất cả các bạn, hôm nay chúng ta sẽ cùng nhau tìm hiểu về Build for Billion trong Android. Nguyên văn của Google là vậy còn chúng ta sẽ hiểu đơn giản là cách xây dựng ứng dụng cho hàng tỉ người dùng, những điều cần tránh, lưu tâm khi phát triển ứng dụng.

1. Tổng quan.

Vâng như các bạn đã biết, thị trường smartphone rất rộng lớn với hàng tỉ người dùng - đồng nghĩa với hàng tỉ khách hàng tiền năng cho các bạn khai thác, để làm được điều này đòi hỏi ứng dụng phải có công nghệ, thiết kế một cách kỹ lưỡng. Bạn không những cần phải đáp ứng những yêu cầu về mặt kỹ thuật mà còn phải đảm bảo nội dung bạn cung cấp phải mới mẻ, độc đáo với người dùng và quan trọng là đem lại những gì mà người dùng mong muốn và thiết kế theo đúng mong muốn đó. Ngoài ra còn vô vàn vấn đề khác như đa ngôn ngữ, yếu tố văn hóa, yếu tố về trình bày văn bản, yếu đố về giới tính tuổi tác của người dùng nói chung là rất rất nhiều vấn đề. Ok vậy là chúng ta đã xong phần giới thiệu bài toán.

2. Chúng ta cần quan tâm những điều gì?

Để giả quyết bài toán đã nêu ở trên và đạt được mục đích Build for Billion chúng ta có những thứ cơ bản cần quan tâm như sau:

  • Connectivity
  • Devide capability
  • Data cost
  • Battery consumption
  • Ui and content

3. Connectivity for billions.

Vấn đề đầu tiên chính là Connectivity. Google họ có từng nói hơn một nửa người dùng trên thế giới đang trải nghiệm các ứng dụng với mạng tốc độ 2g mà chúng ta thì không thể mang 5g đến cho họ được thế nên để cải thiện trải nghiệm của họ, hãy tối ưu hóa ứng dụng cho các kết nối có tốc độ thấp và cung cấp chế độ ngoại tuyến bằng cách lưu trữ dữ liệu và xử lý hình ảnh để có hiệu suất tối ưu.

  • Tối ưu ảnh: Load ảnh luôn là một việc rất tốn kém, về cả mặt tài nguyên phần cứng lẫn tài nguyên mạng, rất may mắn là chúng ta có rất nhiều giải pháp cho vấn đề này như sử dụng các định dạng ảnh nhẹ hơn hay sử dụng các thư viện bên thứ ba v..v.
    • Sử dụng ảnh định dạng WebP: Cái này thì các bạn biết lâu lắm rồi, ảnh định dạng này thường có kích cỡ nhỏ hơn png và jpg với chất lượng ít nhất cũng gần như tương tự kể cả khi chấp nhận sử dụng lossy thì chất lượng ảnh cũng không tệ. Và dĩ nhiên là chúng ta sẽ có ứng dụng load nhanh hơn tiết kiệm dữ liệu hơn. Và cũng từ lâu lắm rồi Android Studio đã hỗ trợ việc chuyển đổi này.
    • Sử dụng hình ảnh có kích thước động: Cái này thì liên quan đến xử lí nhiều hơn. Các bạn sẽ dựa vào thiết bị (ví dụ như cấu hình, loại kết nối mạng hay kích cỡ màn hình v..v) để yêu cầu load về hình ảnh thích hợp. Nếu thiết bị đang sử dụng 2g thì chúng ta load ảnh chất lượng thấp thôi cho người dùng đỡ phải đợi lâu. Ngoài ra các thư viện cũng cung cấp cho chúng ta place holder để tăng trải nghiệm hoặc xịn hơn là cung cấp hình ảnh dưới dạng thumbnail trong quá trình loading .
    • Cuối cùng là sử dụng thư viện bên thứ 3. Thư viện thì có rất nhiều và các nhà phát triển cũng cung cấp các thông số cho chúng ta như cách hiển thị, chất lượng đầu ra, định dạng bit màu v..v. Các bạn sẽ dựa vào các yếu tố này để lựa chọn thư viện. Google có nhắc đến cho chúng ta một vài lựa chọn như Glide hay Picasso.
  • Tối ưu kết nối mạng:
    • Xây dựng chế độ ngoại tuyến: Cái này không chỉ là việc lưu trữ hay cached lại data mà còn là sắp xếp các request vào hàng đợi để có thể sẵn sàng khôi phục khi có kết nối mạng. Nếu có thể, các ứng dụng không nên thông báo cho người dùng rằng kết nối đã bị mất. Chỉ khi người dùng thực hiện một thao tác yêu cầu kết nối mạng thì mới thông báo cho người dùng tránh làm gián đoạn trải nghiệm.
    • Sử dụng Room để lưu trữ dữ liệu.
    • Tránh các request trùng lặp: Lưu trữ tối đa các dữ liệu có thể lưu trữ offline. Ở đây Google có giới thiệu vềDiskLruCache (https://github.com/JakeWharton/DiskLruCache) các bạn có thể tìm hiểu thêm.
  • Điều chỉnh đường truyền dữ liêu: Ứng dụng cần thích ứng với các loại kết nối mạng mà người dùng đang có cũng như các thay đổi có thể xảy ra trong quá trình sử dụng.
    • Ưu tiên băng thông: Ví dụ như là khi người dùng có kết nối 4g và wifi thì đương nhiên là phải sử dụng wifi, bạn cũng cần chuẩn bị cho case mà wifi bị tắt và người dùng quay sang dùng 4g. Dĩ nhiên đây là ví dụ thôi.
    • Load các thông tin hiện hữu cho người dùng, ví dụ nếu người dùng sử dụng mạng 2g thì khi vào ứng dụng mua sắm chảng hạn, các bạn chỉ nên load trang đầu tiên nơi mà người dùng đang trực tiếp tương tác thôi. Các nội dung khác có thể load sau, ví dụ như thông tin ở tab khác chẳng hạn.
    • Sử dụng ít băng thông hơn trên các kết nối chậm hơn: Như trên đã có nói, bạn sẽ quyết định load thông tin gì dựa vào kết nối mạng người dùng, ví dụ việc load một ảnh với 2g và wifi là hoàn toàn khác nhau, với wifi thì ảnh chất lượng cao là ưu tiên còn với 2g thì load được mới là ưu tiên nên khi phát hiện được mạng người dùng kém, bạn chỉ nên request ảnh chất lượng thấp thôi. Để làm điều này các bạn có thể sử dụng:
ConnectivityManager> isActiveNetworkMetered()
ConnectivityManager> getActiveNetworkInfo()
ConnectivityManager> getNetworkCapabilities(Network)
TelephonyManager> getNetworkType()
  • Phát hiện thay đổi mạng và thích ứng với thau đổi đó: Phần này tương tự như trên có điều bạn sẽ sử dụng broadcast CONNECTIVITY_CHANGE để lắng nghe sự kiện thay đổi rồi sau đó kiểm tra lại kết nối mạng.

4. Device capability for billions.

Các thiết bị smart phone thì có vô vàn loại với kích cỡ cấu hình khác nhau và bạn phải đảm bảo làm sao ứng dụng của bạn có thể tiếp cận nhiều người dùng nhất có thể. Để làm được việc đó các bạn cần tối ưu cho nhiều kích cỡ màn, cấu hình thiết bị như Ram chẳng han.

  • Hỗ trợ nhiều kích cỡ màn hình: Điều này các bạn cũng biết cả rồi mình sẽ list lại đơn giản như sau:
    • Sử dụng đơn vị dp để hiển thị (độc lập với pixel, lưu ý vấn đề này khi custom view)
    • Test, vâng kiểm tra trên tất cả các kích cỡ màn hình mà bạn muốn support.
  • Cung cấp khả năng tương thích ngược: Không phải tất cả người dùng của bạn đều đang sử dụng các thiết bị phiên bản mới nhất, tốt nhất của nền tảng Android. Dưới đây là một số cách bạn có thể cải thiện khả năng tương thích ngược, giúp ứng dụng của bạn có sẵn cho nhiều người nhất có thể.
    • Đặt targetSdkVersionminSdkVersion của bạn một cách thích hợp
    • Sử dụng Android Support libraries: Một ví dụ hay gặp nhất đó chính là marterial design, bạn sẽ cần support lib cho các thiết bị dưới 5.0 (Các thiết bị không hỗ trợ)
    • Sử dụng Google Play services: Các dịch vụ Google Play mang đến các API Google tốt và độc lập với phiên bản nền tảng Android. Bạn có thể sử dụng các tính năng từ các dịch vụ Google Play để cung cấp trải nghiệm Google tốt nhất trên thiết bị Android. Một ví dụ có thể kể đến như GcmNetworkManager (https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager)
  • Sử dụng bộ nhớ một cách hiệu quả: Điều chỉnh linh hoạt bộ nhớ của bạn để đảm bảo khả năng tương thích giữa các thiết bị có cấu hình RAM khác nhau. Các phương thức như isLowRamDevice()getMemoryClass() giúp xác định các ràng buộc về bộ nhớ. Dựa trên thông tin này, bạn có thể giảm quy mô sử dụng bộ nhớ của mình. Ví dụ, bạn có thể sử dụng hình ảnh có độ phân giải thấp hơn trên các thiết bị có bộ nhớ thấp.
    • Hạn chế các tiến trình chạy lâu dài: Các tiến trình chạy lâu sẽ lưu lại trong bộ nhớ và có thể làm chậm thiết bị. Vis dụ bạn nên sử dụng Firebase Cloud Messaging (FCM)GcmNetworkManager để tránh các dịch vụ nền chạy lâu và giảm áp lực bộ nhớ trên thiết bị của người dùng.
    • Ngoài ra nếu muốn ở một mức độ cao hơn các bạn có thể Benchmark ứng dụng của bạn, Android Studio đã hỗ trợ việc này từ rất lâu rồi với Android Profiler

5. Reduced data cost for billions.

Gói dữ liệu ở một số quốc gia có thể chiếm tới 10% thu nhập hàng tháng của người dùng thông thường. Điều này có nghĩa là giảm thiểu kích thước tải xuống của ứng dụng và cho phép người dùng kiểm soát cách ứng dụng của bạn sử dụng dữ liệu có thể mang lại lợi ích lớn cho nhiều người dùng. Giảm thiểu kích thước tải xuống cũng giúp tiết kiệm không gian trong bộ nhớ trong. Bạn có thể thực hiện một số cách để giúp tối ưu hóa lượng dữ liệu mà ứng dụng của bạn sử dụng, cả qua mạng và trong bộ nhớ trong.

  • Giảm kích thước ứng dụng: Thư mục asset luôn là nơi làm cho kích cỡ ứng dụng phình to. Cái này thì ai cũng biết và rồi thì lại có ai đó quên. Đầu tiên là:
    • Sử dụng ảnh vector, ảnh định dạng này rất nhỏ và có thể scale được nên nếu có thể nên dùng.
    • Ở các chỗ không thể dùng ảnh vector được thì các bạn sử dụng ảnh đinh dạng Webp.
    • Ngoài ra các bạn cũng có thể sử dụng Multi Apk để giảm thiểu kích cỡ ứng dụng cho từng loại thiết bị.
    • Ngoài ra các bạn có thể thấy một số game hay ứng dụng lớn họ hay tách các mục ra thành phần download riêng, người dùng sẽ chọn những package mà họ muốn để download xuống.
  • Giảm thiểu kích thước code: Android hỗ trợ việc này từ rất lâu rồi với ProGuard. Các bạn cũng có thể bật resource shrinking bằng cách cài đặt minifyEnabled=true, shrinkResources=true trong file build.gradle của bạn.
  • Hỗ trợ di chuyển app sang thẻ nhớ ngoài bằng cách cài đặt thẻ android:installLocation trong file Manifest của ứng dụng.
  • Kiểm tra bộ nhớ cached của ứng dụng, ví dụ như google chrome có thể lên đến mấy trăm Mb dữ liệu cached. Mình không chê nó tệ mà muốn ví dụ là bộ nhớ này có thể rất lớn và việc phình to này sẽ chiếm rất nhiều bộ nhớ. Hãy chắc chắn rằng bạn đã đặt dữ liệu được lưu trong bộ nhớ cache của mình vào getCacheDir() - hệ thống có thể xóa các tệp được đặt ở đây khi cần.
  • Cuối cùng là cung cấp tùy chọn mạng cho người dùng: Nhiều ứng dụng trong mục cài đặt có tùy chọn mạng dữ liệu di động hay wifi cho người dùng, việc này rất tốt cho trải nghiệm người dùng.

6. Reduce battery consumption.

  • Ứng dụng của bạn nên giảm thiểu hoạt động khi chạy ở chế độ nền và khi thiết bị chạy bằng nguồn pin.
  • Hạn chế sử dụng các cảm biến, chẳng hạn như cảm biến GPS, có thể tiêu hao pin rất nhiều. Bạn có thể sử dụng API FuseLocationProviderđể quản lí vị trí một cách cơ bản. Nó cung cấp một API đơn giản để bạn có thể chỉ định các yêu cầu, chẳng hạn như độ chính xác cao hoặc mức sử dụng pin thấp. Nó cũng tối ưu hóa việc sử dụng năng lượng pin của thiết bị bằng cách lưu trữ các vị trí.
  • Hạn chế Wake Lock. Tránh sử dụng Wake Lock vì chúng ngăn thiết bị chuyển sang trạng thái năng lượng thấp. Điều này làm cho thiết bị tốn rất nhiều pin trong thời gian chờ.
  • Sử dụng GcmNetworkManager để lên lịch các tác vụ và cho phép các dịch vụ Google Play hoạt động trên hệ thống. Điều này giúp đơn giản hóa rất nhiều công phổ biến chẳng hạn như chờ kết nối mạng, trạng thái sạc của thiết bị v..v. Sử dụng GcmNetworkManager để thực hiện hoạt động nền không cần thiết khi thiết bị đang sạc và được kết nối với mạng.

7. UI and content for billions.

  • Giao diện người dùng nhanh và nhạy: Phản hồi chạm với các items có thể chạm: Phản hồi cảm ứng tạo ra thêm một cảm giác xúc giác cho giao diện người dùng. Bạn nên đảm bảo ứng dụng của bạn cung cấp phản hồi cảm ứng trên tất cả các yếu tố có thể chạm để giảm độ trễ ứng dụng.
  • Giao diện người dùng phải luôn tương tác được: Trải nghiệm người dùng sẽ rất tệ nếu tại một thời điểm nào đó mà người dùng không thể tương tác được với giao diện mà họ đang nhìn thấy.
  • Đặt mục tiêu 60 khung hình mỗi giây trên các thiết bị giá rẻ: Android sẽ refresh màn hình ở tốc độ 60 hình trên giây điều này nghĩa là đâu đó bạn có 16ms để thực hiện các thay đổi. Có thể cân nhắc bỏ bớt các animation trên các thiết bị yếu.
  • Sử dụng màn hình khở động trên các ứng dụng khởi động chậm: Các ứng dụng này thường cần load nhiều dữ liệu đầu vào. Việc thiết kế một màn hình khởi động khoảng một vài giây sẽ không làm người dùng thấy phiền lòng thay vì phải nhìn một màn hình trắng tinh vì load dữ liệu quá lâu.
  • Ngoài ra các bạn cũng cần quan tâm đến support đa ngôn ngữ và RTl layout để thích hợp các khu vực, các địa phương khác nhau: Tham khảo thêm với ICU4J Android Framework APIs hoặc Support different languages and cultures (https://developer.android.com/training/basics/supporting-devices/languages.html)

8. Tổng kết.

Trên đây mình đã giới thiệu sơ qua về Build for Billion mà Google có hướng dẫn. Cảm ơn các bạn đã theo dõi bài viết. Các bạn cũng có thể tham khảo nguồn của bài viết này tại trang https://developer.android.com/guide