Tôi bối rối không biết khi nào người ta sẽ chọn AsyncTask thay cho Handler. Nói rằng tôi có một số mã tôi muốn chạy mỗi n giây sẽ cập nhật giao diện người dùng. Tại sao tôi lại chọn cái này?
Tôi bối rối không biết khi nào người ta sẽ chọn AsyncTask thay cho Handler. Nói rằng tôi có một số mã tôi muốn chạy mỗi n giây sẽ cập nhật giao diện người dùng. Tại sao tôi lại chọn cái này?
Câu trả lời:
IMO, AsyncTask được viết để cung cấp một cách thuận tiện, dễ sử dụng để đạt được xử lý nền trong các ứng dụng Android, mà không phải lo lắng quá nhiều về các chi tiết cấp thấp (chủ đề, vòng lặp thông báo, v.v.). Nó cung cấp các phương thức gọi lại giúp lên lịch các tác vụ và cũng dễ dàng cập nhật giao diện người dùng bất cứ khi nào cần thiết.
Tuy nhiên, điều quan trọng cần lưu ý là khi sử dụng AsyncTask, nhà phát triển đang tuân theo các giới hạn của nó, điều này dẫn đến các quyết định thiết kế mà tác giả của lớp đã đưa ra. Ví dụ, gần đây tôi phát hiện ra rằng có giới hạn số lượng công việc có thể được lên lịch bằng AsyncT task.
Handler minh bạch hơn trong hai và có thể giúp bạn tự do hơn; vì vậy nếu bạn muốn kiểm soát nhiều hơn những thứ bạn sẽ chọn Handler nếu không AsynTask sẽ hoạt động tốt.
AsyncTasksđược thực thi trên một luồng, do đó không còn song song nữa. Bạn vẫn có thể chạy chúng khi Executorthực hiện paralel .
Quy tắc ngón tay cái của tôi sẽ là:
Nếu bạn đang làm một cái gì đó tách biệt liên quan đến UI, ví dụ như tải xuống dữ liệu để trình bày trong danh sách, hãy tiếp tục và sử dụng AsyncTask.
Nếu bạn đang thực hiện nhiều tác vụ lặp lại, ví dụ như tải xuống nhiều hình ảnh sẽ được hiển thị trong ImageViews(như tải xuống hình thu nhỏ) khi tải xuống, hãy sử dụng hàng đợi tác vụ với Handler.
Luôn cố gắng tránh sử dụng AsyncTask khi có thể chủ yếu vì các lý do sau:
AsyncTask không được đảm bảo để chạy vì có một cơ sở ThreadPool và kích thước tối đa được thiết lập bởi hệ thống và nếu bạn tạo quá nhiều asynctask thì cuối cùng chúng sẽ bị hủy
AsyncTask có thể tự động chấm dứt, ngay cả khi đang chạy, tùy thuộc vào vòng đời hoạt động và bạn không có quyền kiểm soát đối với nó
Các phương thức AsyncTask chạy trên Giao diện người dùng, như onPostExecute, có thể được thực thi khi Hoạt động mà nó đề cập đến, không hiển thị nữa hoặc có thể ở trạng thái bố cục khác, như sau khi thay đổi hướng.
Tóm lại, bạn không nên sử dụng các phương thức được liên kết với UIThread của AsyncTask, đây là ưu điểm chính của nó !!! Ngoài ra, bạn chỉ nên làm công việc không quan trọng trên doInBackground. Đọc chủ đề này để hiểu thêm về vấn đề này:
Là AsyncTask thực sự thiếu sót về mặt khái niệm hay tôi chỉ thiếu một cái gì đó?
Để kết luận, hãy thử sử dụng IntentService, HandlerThread hoặc ThreadPoolExecutor thay vì AsyncTask khi bất kỳ vấn đề nào được trích dẫn ở trên làm bạn lo lắng. Chắc chắn nó sẽ đòi hỏi nhiều công việc hơn nhưng ứng dụng của bạn sẽ an toàn hơn.
Nếu bạn muốn thực hiện phép tính mỗi x giây, có lẽ bạn nên lên lịch Runnablecho một Handler(với postDelayed()) và điều đó Runnablesẽ bắt đầu trong luồng UI hiện tại. Nếu bạn muốn bắt đầu nó trong một chủ đề khác, hãy sử dụng HandlerThread. AsyncTask dễ sử dụng hơn đối với chúng tôi nhưng không tốt hơn xử lý.
Handler được liên kết với luồng chính của ứng dụng. nó xử lý và lên lịch các tin nhắn và runnables được gửi từ các luồng nền đến luồng chính của ứng dụng.
AsyncTask cung cấp một phương pháp đơn giản để xử lý các luồng nền để cập nhật giao diện người dùng mà không chặn nó bởi các hoạt động tốn thời gian.
Câu trả lời là cả hai có thể được sử dụng để cập nhật giao diện người dùng từ các luồng nền, sự khác biệt sẽ nằm trong kịch bản thực hiện của bạn. Bạn có thể xem xét sử dụng trình xử lý mà bạn muốn gửi tin nhắn bị trì hoãn hoặc gửi tin nhắn đến MessageQueue theo một thứ tự cụ thể.
Bạn có thể cân nhắc sử dụng AsyncTask nếu bạn muốn trao đổi các tham số (do đó cập nhật giao diện người dùng) giữa luồng chính của ứng dụng và luồng nền theo cách dễ dàng thuận tiện.
AsyncTaskgiả sử bạn sẽ làm một cái gì đó trên luồng UI, sau khi một số công việc nền kết thúc. Ngoài ra, bạn chỉ có thể thực thi nó một lần (sau đó, trạng thái của nó là FINISHEDvà bạn sẽ có một ngoại lệ khi cố gắng thực hiện nó một lần nữa). Ngoài ra, tính linh hoạt của việc sử dụng nó là không nhiều. Có, bạn có thể sử dụng THREAD_POOL_EXECUTORđể thực hiện song song, nhưng nỗ lực có thể không xứng đáng.
Handlerkhông giả định bất cứ điều gì, ngoại trừ xử lý Runnables và Tin nhắn. Ngoài ra, nó có thể được chạy nhiều lần như bạn muốn . Bạn có thể tự do quyết định nó phải được gắn vào chủ đề nào, cách nó giao tiếp với các trình xử lý khác, có thể sản xuất chúng với HandlerThread. Vì vậy, nó linh hoạt hơn nhiều và phù hợp với một số công việc lặp đi lặp lại.
Kiểm tra các loại Handlerví dụ khác nhau ở đây .
Họ là câu hỏi phỏng vấn tốt nhất được hỏi. AsyncTask - Chúng được sử dụng để giảm tải luồng UI và thực hiện các tác vụ trong nền. Trình xử lý - Android dosent có cách giao tiếp trực tiếp giữa UI và luồng nền. Trình xử lý phải được sử dụng để gửi tin nhắn hoặc có thể chạy qua hàng đợi tin nhắn.
Vì vậy, AsyncT task được sử dụng khi các tác vụ cần thiết được thực thi trong nền và Trình xử lý được sử dụng để liên lạc giữa UI và Chủ đề nền.
doInBackground - về cơ bản không hoạt động trong một chủ đề khác. onPostExecute - đăng kết quả lên luồng UI và nó đang gửi tin nhắn nội bộ đến bộ xử lý của luồng chính. Giao diện người dùng chính đã có một looper và xử lý liên kết với nó.
Vì vậy, về cơ bản, nếu bạn phải thực hiện một số tác vụ nền, hãy sử dụng AsyncTask. Nhưng cuối cùng, nếu một cái gì đó cần được cập nhật trên UI, nó sẽ sử dụng trình xử lý của luồng chính.