Tạo Ứng Dụng Mượt (tránh ARN)
![](https://resources.blogblog.com/img/icon18_edit_allbkg.gif)
https://hocdelamduocviec.blogspot.com/2014/03/tao-ung-dung-muot-tranh-arn.html
Các Trigger ARN là gì?
Trong Android, khả tính đáp ứng của ứng dụng được giám sát bởi dịch vụ hệ thống Activity Manager và Windown Manager. Android sẽ hiển thị hộp thoại ARN cho một ứng dụng khi nó phát hiện một trong những điều kiện sau:- Không đáp ứng thao tác người dùng (ví dụ: sự kiện nhấn phím hoặc chạm màn hình) trong vòng 5 giây.
- BroadCastReceiver chưa thực thi xong trong vòng 15 giây.
Cách tránh ARN
Thông thường các ứng dụng Android chạy hoàn toàn trên thread đơn mặc định là UI thread hoặc main thread. Điều này có nghĩa là bất cứ ứng dụng nào của bạn đang chạy trên UI thread mà tốn nhiều thời gian để hoàn thành sẽ có thể kích hoạt hộp thoại ARN bởi vì ứng dụng của bạn khi đó không thể xử lý các sự kiện đầu vào hoặc các quảng bá Intent (Intent broadcasts).
Do đó, bất cứ phương thức chạy trong UI thread nên thao tác càng ít càng tốt trong thread đó. Đặc biệt, các Activity nên làm càng ít càng tốt để cài đặt các phương thức chu kỳ sống (life-cycle) quan trọng như onCreate () và onResume (). Các thao tác có khả năng thực hiện trong một thời gian dài như là các thao tác mạng (network) hoặc dữ liệu (database), hoặc các tính toán tốn kém về mặt tính toán như là thay đổi kích thước các bitmap nên được thực hiện trong một thread riêng (worker thread) (hoặc trong trường hợp của các thao tác dữ liệu, thông qua các yêu cầu bât đồng bộ (asynchronous).
Cách hiệu quả nhất để tạo một thread riêng (worker thread) cho các thao tác lâu là dùng class AsynTask. Chúng ta kế thừa(extend) AsynTask và triển khai (implement) phương thức doInBackground() để thực hiện công việc. Để hiển thị tiến trình thay đổi (progress changes) tới người dùng, bạn có thể gọi publishProgress(), nó sẽ gọi ngược lại phương thức onProgressUpdate(). Trong hàm triển khai onProgressUpdate() (chạy trong UI thread), bạn có thể thông báo tới người dùng. Ví dụ:
Để thực thi thread riêng này (this worker thread), bạn chỉ cần tạo thể hiện (instance) và gọi phương thức excute():Mặc dù phức tạp hơn AsynTask, bạn có thể tạo class Thread hoặc HandlerThread riêng. Nếu tạo, bạn nên thiết lập (set) độ ưu tiên cho thread đó là "background" bằng cách gọi Process.setThreadPriority() và truyền THREAD_PRIORITY_BACKGROUND. Nếu bạn không thiết lập thread đó tới độ ưu tiên thấp nhất theo cách này.Khi đó, thread đó vẫn còn làm chậm ứng dụng của bạn bởi vì mặc định nó sẽ được thực thi với mức độ ưu tiên như UI thread.
Nếu bạn cài đặt (implement) Thread hoặc HandlerThread, chắc chắn ràng UI thread không đóng (block) trong lúc đợi thread riêng (worker thread) hoàn thành - đừng gọi Thread.wait() hoặc Thread.sleep(). Nên đóng (intead of blocking) khi đợi một thread riêng (a worker thread) hoàn thành, main thread của bạn nên cung cấp một Handler cho các Thread khác để gửi trở lại khi hoàn thành. Khi thiết kế ứng dụng của bạn theo cách này sẽ cho phép UI thread của ứng dụng bạn duy trì khả năng đáp ứng cho đầu vào sẽ tránh hiện hợp thoại ARN - gây ra khi quá thời gian sự kiện đầu vào 5 giây.
Các hạn chế cụ thể về thời gian thực thi BroadCastReceiver chú trọng những gì các bộ nhận quảng bá (Broadcast receiver) nhằm để làm: nhỏ, số lượng riêng biệt công việc trong chế độ nền (background) như là lưu cài đặt (setting) hoặc đăng kí thông báo (notification). Vì vậy, các phương thức khác được gọi trong UI thread, các ứng dụng nên tránh các thao tác hoặc tính toán có khả năng lâu trong broadcast receiver. Thay vào đó, ta nhân tập trung sâu vào các công việc thông qua các thread riêng (worker threads), úng dụng của bạn nên khởi động một IntentService nếu một thao tác có thể lâu cần được thực thi để đáp ứng một Intetn broadcast.
Tip: Bạn có thể dùng StrictMode để giúp tìm các thao tác có khả năng làm lâu như là các thao tác mạng hoặc dữ liệu mà bạn có thể vô tình đang thực hiện trong main thread.
Tăng cường khả năng đáp ứng
Thông thường, 100 đến 200 ms là ngưỡng trên mà người dùng có thể nhận ra sự chậm chạp của ứng dụng. Do vậy, đây là một số mẹo bổ sung ngoài những gì bạn nên làm để tránh ARN và khiến cho ứng dụng của bạn có vẻ mượt đối với người dùng:
- Nếu ứng dụng của bạn đang làm việc trong chế độ nền (background) để đáp ứng đầu vào người sử dụng (user input), hiển thị tiến trình đang thực hiên đó (như là dùng một ProgressBar trong UI thread).
- Đối với các trò chơi cụ thể, thực hiện các phép tính cho di chuyển trong một thread riêng (worker thread).
- Nếu ứng dụng của bạn có một giai đoạn cài đặt ban đầu tốn thời gian, để ý đến việc hiển thị một màn hình khởi động hoặc tạo ra màn hình chính càng nhanh càng tốt, cho thấy việc tải (loading) đang được tiến hành và điền các thông tin bất đồng bộ. Trong cả hai trường hợp, bằng cách nào đó tiến độ công việc đang được thực hiện, vì sợ rằng người dùng nhận thấy ứng dụng đó đang bị đơ (frozen).
- Sử dụng hiệu quả các công cụ như Systrace và Traceview để xác định tắc nghẽn trong khả năng đáp ứng của ứng dụng bạn.