2011-01-29 27 views
9

Trong một kịch bản mà tôi có một giao diện người dùng sẽ được cập nhật từ một thread riêng biệt (sử dụng AsyncTask), tôi có thể xác định AsyncTask như một lớp bên trong của hoạt động này, nhưng điều này có hai nhược điểm tôi thấy có vấn đề:Làm cách nào để thực hiện thay đổi giao diện người dùng hoạt động từ Android AsyncTask?

  1. nó làm cho các tập tin nguồn rất lớn, làm giảm hiệu quả trong việc quản lý mã
  2. nó làm cho nó khó có thể tái sử dụng các lớp chủ đề

một giải pháp tốt là gì? Sử dụng một lớp bên trong, nhưng trừu tượng tất cả mọi thứ nó làm cho các lớp khác? Chuyển tham chiếu đến Hoạt động tới AsyncTask? Luôn định nghĩa lớp AsyncTask là lớp bên trong và chỉ chấp nhận tệp nguồn sẽ lớn?

Trả lời

2

Khá một vài ví dụ tôi đã thấy chỉ cần chuyển một số Context vào hàm tạo của AsyncTask.

public class BackgroundStuff extends AsyncTask<Void, Void, Void> { 
    ... 
    Context mContext; 
    ... 
    BackgroundStuff(Context context){ 
     super(); 
     this.mContext = context; 
    } 
    ... 
} 

Tôi muốn biết liệu có ai khác sử dụng bất kỳ phương pháp tiếp cận nào khác không.

+0

Chuyển ngữ cảnh đến lớp học là những gì tôi hiện đang làm, có vẻ như khá lộn xộn, nhưng có thể không có cách nào tốt hơn. –

13

Trước hết: khi sử dụng AsyncTask bạn không được thực hiện hoạt động giao diện người dùng trong phạm vi doInBackground().

Điều bạn có thể làm là - nếu bạn muốn, ví dụ: trạng thái cập nhật cho công việc nền dài chạy, là publishProgress(values) từ doInBackground(). Thời gian chạy sau đó sẽ cho các giá trị đó gọi số gọi lại onProgressUpdate(values) của bạn, chạy trong chuỗi giao diện người dùng và từ nơi bạn có thể cập nhật giao diện người dùng.

Hãy xem ví dụ: https://github.com/pilhuhn/ZwitscherA/blob/master/src/de/bsd/zwitscher/TweetListActivity.java#L336 để xem ví dụ.

AsyncTask có thể được triển khai trong một tệp lớp riêng.

+0

Phương thức doInBackground() không thể truy cập giao diện người dùng, khung công tác ném một ngoại lệ nếu nó cố gắng. Nhưng câu hỏi của tôi liên quan nhiều hơn đến cách lớp con AsyncTask thực sự truy cập vào giao diện người dùng. –

+0

@Olli đây là những gì tôi nói: doInBackgrround() không được truy cập vào giao diện người dùng. Hoặc làm điều đó trước hoặc sau với onPre | PostExecute() hoặc ở giữa bằng cách xuất bản tiến trình. Ba phương thức gọi lại này được phép truy cập vào giao diện người dùng –

0

Tôi có một POV hơi kỳ quặc với AsyncTasks vì tôi thường thích sử dụng Chủ đề bình thường, nhưng về cơ bản là cách tôi thực hiện một tác vụ chạy nền và cập nhật một giao diện người dùng là tạo ra một Handler vào cuối của phương pháp onCreate(), tôi sẽ sau đó ghi đè lên phương thức handleMessage (Message msg).

Sau đó, trong Chủ đề của mình, tôi sẽ chuyển Trình xử lý dưới dạng tham số, khi tôi muốn cập nhật, tôi sẽ gửi một thông báo từ chuỗi đến Trình xử lý, bây giờ điều này là giao tiếp từ chuỗi nền vào chuỗi giao diện người dùng để xử lý công việc trên giao diện người dùng.

Bây giờ tôi tưởng tượng AsyncTasks thực hiện một tác vụ tương tự nhưng loại bỏ sự cần thiết phải thực hiện ghi đè phương thức handleMessage của Trình xử lý.

Thật thú vị khi tìm hiểu thêm về bất kỳ ưu điểm/nhược điểm nào giữa hai cách tiếp cận này.

+0

Tôi đã sử dụng Trình xử lý ban đầu, nhưng tôi đã không thực hiện với nó, mặc dù đó là một nhận thức hoàn toàn chủ quan.Tôi thích sự rõ ràng của AsyncTask, và tôi thường chia chúng thành các lớp riêng biệt (chứ không phải là lớp bên trong) giúp tôi làm việc với nó, và giữ cho lớp con Hoạt động dễ quản lý hơn. –

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