2011-08-26 36 views
9

1) Tôi không đánh giá thấp lý do tại sao các mẫu của Android hầu như sử dụng AsyncTasks như các lớp bên trong riêng tư. Tôi biết nó là thuận tiện để làm cho nó bên trong lớp học nhưng nó làm cho tập tin lớp học của chúng tôi dài hơn và khó đọc. ShelvesActivity of Shelves ứng dụng mẫu có thậm chí 845 dòng. Bạn không nghĩ rằng đó là một thiết kế xấu hoặc xây dựng xấu?Nếu AsyncTask không phải là một lớp bên trong ... - một số câu hỏi

2) Nếu tôi tạo lớp bên ngoài ScanStorageTask của mình, tôi phải chuyển sang điều gì? toàn bộ Hoạt động hoặc chỉ sử dụng các tiện ích con?

Ví dụ: Nếu tôi phải sử dụng WebView, Nút và ProgressBar trong ScanStorageTask. tôi sử dụng này:

ScanStorageTask task = new ScanStorageTask(this); // "this" is activity reference, then get the webView, button, progressBar from it. 

hay này:

ScanStorageTask task = new ScanStorageTask(webView, button, progressBar); 

Trả lời

14

Không có gì sai khi thực hiện nó bên ngoài và thực sự có thể là thiết kế tốt hơn. Việc chuyển các phần tử giao diện người dùng xung quanh là loại khớp nối chặt chẽ có thể khiến bạn gặp rắc rối khi bạn có cơ sở mã thực sự lớn.

Tại sao không làm điều đó bên ngoài và sử dụng mẫu "người nghe" mà các điều khiển giao diện người dùng sử dụng?Làm cho lớp ScanStorageTask của riêng bạn, tạo ra một giao diện OnCompleteListener với một phương thức onComplete, và chuyển giao nó cho cá thể ScanStorageTask của bạn (phơi bày một phương thức setOnCompleteListener hoặc một cái gì đó với hiệu ứng đó). Sau đó, onPostExecute chỉ có thể làm điều này:

if(onCompleteListener != null) 
    onCompleteListener.onComplete(data); 

Bằng cách đó, bạn xác định giao diện người dùng cập nhật của bạn bên trong hoạt động của mình dựa trên các dữ liệu . Tốt hơn là tách mối quan tâm và sẽ giữ cho dòng mã của bạn trên mỗi lớp xuống, vì đó dường như là những gì bạn muốn. Nếu bạn chưa có điều này, hãy tạo một lớp đại diện cho dữ liệu bạn cần truyền vào và thoát ra, và đó là những gì bạn truyền vào nhiệm vụ như một tham số cho phương thức execute và những gì onPostExecute chuyển tới onComplete.

+0

Bạn nói đúng, qua các yếu tố giao diện người dùng rất phiền hà. Tôi thực sự muốn làm điều gì đó để tách AsyncTask khỏi Hoạt động. Cảm ơn về ý tưởng mẫu người nghe. – Emerald214

+0

Tôi muốn bạn có một mẫu mã số – CodyBugstein

+1

@Imray Hãy cho tôi biết nếu điều này có ích. Tôi đã tạo lớp này và giờ tôi sẽ mở rộng nếu cho tất cả các tác vụ không đồng bộ của mình: https://github.com/aguynamedrich/beacon-utils/blob/master/Library/src/us/beacondigital/utils/tasks/Task.java – Rich

6

lớp Inner phép bạn thao tác giao diện người dùng của một bên ngoài Activity bên onPreExecute(), onPostExecute()onProgressUpdate() mà không đi qua các cấu trúc giao diện người dùng hoàn toàn (s) để AsyncTask. Bạn chỉ có thể sử dụng các hàm hoạt động cho điều đó.

Điều này rất hữu ích vì thao tác với giao diện người dùng không phải là mục đích chính của AsyncTask. Nó đang làm công việc nền không phải UI. Và cho rằng, những gì bạn thường phải vượt qua là một số đối số để thực hiện công việc này (ví dụ: cung cấp URL để tải xuống tệp).

Khi bạn khai báo AsyncTask bên ngoài, về cơ bản bạn không thể truy cập tài nguyên UI bên trong onPreExecute() (không có đối số nào được chuyển cho điều này) và rất khó bên trong hai hàm UI khác.

Tôi muốn nói AsyncTask chỉ được thực hiện cho việc sử dụng ong làm lớp bên trong để làm việc và cập nhật giao diện người dùng. Xem mô tả:

AsyncTask cho phép sử dụng đúng và dễ dàng chuỗi giao diện người dùng. Lớp này cho phép thực hiện thao tác nền và xuất bản kết quả trên giao diện người dùng mà không cần phải thao tác các chủ đề và/hoặc trình xử lý.

(từ the class documentation)

+0

Đã chuyển sang vấn đề mô phỏng này tối qua với httpRequest được tạo luồng. Khi yêu cầu trả về một thông báo cho trình xử lý, tôi muốn làm mới nội dung hoạt động của mình, nhưng không thể kể từ khi nó ở trong một lớp bên ngoài. Tôi sẽ nói rằng trong Android và các hệ thống di động khác đôi khi nó làm cho nhiều hơn kể từ khi làm hầu hết mọi thứ bên trong hoạt động. Bạn mất khả năng đọc nhưng rất có thể lưu một số chu kỳ – NSjonas

+0

Xem/Dữ liệu hoạt động thường được chuyển đến AsyncTask trong hàm tạo của nó. –

2
  1. Cá nhân tôi luôn tin rằng nếu bạn sử dụng lớp chỉ tại một thời điểm, sau đó nó có thể đọc được hầu hết cũng để xác định nó ở đó - vì thế anon lớp bên trong.

  2. Nó không quan trọng. Từ quan điểm thiết kế, tôi chỉ truyền dữ liệu thực sự cần thiết. Tuy nhiên, bạn cần phải biết về một sự cố có thể xảy ra - khi cá thể hoạt động bị ngừng hoạt động (ẩn hoặc định hướng thay đổi) và chuỗi nền của bạn vẫn chạy và cố gắng hiển thị một số thay đổi, bạn có thể gặp phải nhiều lỗi hoặc không hiển thị gì cả.

4

Tôi gặp vấn đề tương tự trong ứng dụng có thể. Tôi muốn thiết lập một sự cộng tác với PC bằng cách sử dụng Socket và tôi muốn mã của tôi có thể được sử dụng lại từ một số Hoạt động/Phân đoạn. Trước tiên, tôi đã cố gắng không sử dụng một lớp bên trong nhưng rất thuận tiện khi bạn phải cập nhật giao diện người dùng để tôi tìm ra giải pháp thay thế:
Tôi đã tạo ra một lớp học ngoài để phụ trách giao tiếp với pc và tôi tạo ra các lớp bên trong trong mỗi hoạt động/mảnh của tôi chỉ với một ghi đè của phương pháp onPostExecute(). theo cách này tôi có thể sử dụng lại mã của mình VÀ cập nhật giao diện người dùng.

Nếu bạn chỉ muốn nhận được kết quả của nhiệm vụ và nếu đáp ứng không cần thiết cho ứng dụng của bạn, bạn có thể sử dụng phương thức get() của lớp AsyncTask.

+0

Sử dụng 'get()' là chính xác những gì nên được sử dụng trong trường hợp bạn chỉ cần kết quả của quá trình nền của bạn. Làm việc như một say mê! – kaolick

Các vấn đề liên quan