2010-04-27 33 views
6

Có thể nào, từ bên trong AsyncTask không phải là lớp bên trong của lớp Activity đang hoạt động, để tham chiếu đến cá thể Hoạt động được khởi tạo thực thi AsyncTask?Nhận tham chiếu đến hoạt động gọi từ AsyncTask (KHÔNG phải là lớp bên trong)

Tôi biết là this thread, tuy nhiên nó không chính xác giải quyết cách tham khảo Hoạt động gọi điện. Một số gợi ý chuyển một tham chiếu đến Activity như một tham số cho constructor AsyncTask, tuy nhiên, nó được báo cáo rằng làm như vậy sẽ luôn dẫn đến một NullPointerException.

Vì vậy, tôi đang thua lỗ. AsyncTask của tôi cung cấp chức năng mạnh mẽ và tôi không muốn phải sao chép nó dưới dạng lớp bên trong trong mọi hoạt động muốn sử dụng nó. Phải có một giải pháp thanh lịch.

Trả lời

10

Các "giải pháp tao nhã" là để thực sự thử đi qua nó như một tham số (để các nhà xây dựng hoặc execute()) và xem nếu nó hoạt động, chứ không phải là giả sử người hỏi rằng câu hỏi trước (sau đó đã trả lời câu hỏi của riêng mình hai lần) biết anh ta đang làm gì. Tôi có thể nghĩ rằng không có gì bên trong là AsyncTask có thể gây ra Activity để trở thành một tham số hàm tạo xấu và mọi đối tượng khác đều tốt.

Hiện tại, tôi chưa vượt qua một số Activity (hoặc khác Context) làm tham số cho AsyncTask, bởi vì AsyncTasks của tôi luôn là các lớp bên trong riêng tư. Trong thực tế, thực tế là bạn muốn công khai AsyncTask đối với tôi là một mùi mã, đề xuất các tác vụ này nên được trung gian bởi một Service hoặc một số điểm kiểm soát khác. Nhưng, đó chỉ là tôi.

CẬP NHẬT

Một câu trả lời tốt hơn để xử lý mô hình này có thể được tìm thấy ở đây: Background task, progress dialog, orientation change - is there any 100% working solution?

+0

Point đưa vào chỉ * cố gắng * nó cho bản thân mình đầu tiên. Tôi tò mò như thế nào bạn sẽ xử lý tình hình của tôi sau đó: Nó không có gì phức tạp; Về cơ bản, tôi đang cố gắng tạo một DownloadFileTask để thực hiện một yêu cầu GET cơ bản trên các URL được truyền, và sau đó ứng dụng sẽ làm những việc khác nhau với các tệp đã tải xuống dựa trên hoạt động/trạng thái hiện tại. Tôi có các hoạt động khác nhau cần tải xuống tệp cho các mục đích khác nhau. Điều này có nên thực hiện tốt hơn với một dịch vụ hoặc một số giải pháp khác không? – stormin986

+4

Ah, tôi hiểu rồi. Bạn có hai lựa chọn khi tôi nhìn thấy nó. Một là để làm cho 'DownloadFileTask' công khai nhưng trừu tượng, và có các lớp bên trong riêng tư thực hiện điều đó cho những thứ duy nhất cho một hoạt động cụ thể. Cách khác là làm cho 'DownloadFileTask' công khai và truyền * cái gì đó * vào hàm tạo. Trong trường hợp này, để giảm thiểu sự ghép nối, có thể bạn không muốn truyền một 'Hoạt động', nhưng một số loại giao diện khác giới hạn những gì mà 'AsyncTask' có thể làm. Bằng cách đó, bạn có thể chọn triển khai giao diện trên 'Hoạt động', hoặc dưới dạng một đối tượng riêng biệt hoặc bất kỳ thứ gì. – CommonsWare

+0

CW, bạn đã rất hữu ích trên rất nhiều của tôi? S, vì vậy cảm ơn! Nếu tôi thực sự có thể chuyển một thể hiện Hoạt động của tôi cho AsyncTask công cộng, tôi nghĩ đó là cách tốt nhất để đến đây. Bạn đề cập đến giảm thiểu khớp nối ... chính xác những gì bạn có nghĩa là bởi điều này và những loại tình huống nào bạn thường muốn tránh với nó? – stormin986

4

My AsyncTask s luôn sống trong một gói riêng biệt trong khi vẫn ràng buộc với một loại hình cụ thể của Activity. Chúng chấp nhận instance của nó trong constructor và lưu trữ trong một biến cục bộ.
Hãy thử suy nghĩ về cách tạo lớp trừu tượng Activity đóng gói AsyncTask nội dung có liên quan và được mở rộng bởi các hoạt động khác.
Giống như vậy:

public abstract RemoteListActivity<T> extends ListActivity{ 

// calls AsyncTask, shows spinning progress dialog, etc 

protected abstract T someConcreteMethod(); 

} 

public final class CustomerListActivity extends RemoteListActivity<Customer>{ 

protected final Customer someConcreteMethod(); 

} 

Ngoài ra, nếu mọi thứ không phù hợp trong một hệ thống phân cấp duy nhất, có một giao diện:

interface LazyLoadable { 
    void setLoadingState(); 
    void setDefaultState(); 
} 

public class MyActivity extends Activity implements LazyLoadable{ 
} 

public final class AsyncTask extends AsyncTask<Void, Void, Void>{ 

    private final LazyLoadable lazyLoadable; 

    public MyAsyncTask(Context ctx, LazyLoadable lazyLoadable){ 
     super(ctx); 
     this.lazyLoadable = lazyLoadable; 
    } 

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