2016-01-26 14 views
5

Tôi đang cố gắng tích hợp Trang bị công việc 2 và Hàng đợi ưu tiên Android bằng cách sử dụng Dagger 2.Làm cách nào để chèn một đối tượng vào Hàng đợi công việc ưu tiên Android với Dagger 2?

Có thể tôi đang sử dụng mẫu sai ở đây (tôi mới sử dụng Java và Android), nhưng tôi đang cố gắng để truy cập một cá thể Retrofit do Dagger tạo ra từ một đối tượng sẽ được tuần tự hóa sau đó được deserialized trước khi thực hiện (Hàng đợi công việc Android nối tiếp các công việc được tiếp tục lưu vào đĩa). Ví dụ Retrofit được tạo bởi một thành phần Application Dagger, bởi vì tôi đang sử dụng SharedPreferences ở một trong các phụ thuộc của nó.

Tôi không thể chuyển trang bị thêm vào công việc khi nó được tạo vì không thể tự trang bị thêm.

Ứng dụng cũng không thể được tuần tự hóa, vì vậy tôi không thể tham chiếu thành phần Application Dagger từ công việc khi nó chạy (vì tôi không thể tiêm ((MyApplication) myApplication).component().inject(this); như tôi có thể làm từ hoạt động, vì đối tượng ứng dụng không tồn tại trong công việc được giải tuần tự hóa.)

Tôi muốn sử dụng phiên bản Retrofit được sử dụng bởi phần còn lại của ứng dụng để có hiệu quả thay vì tạo một thể hiện khác cho công việc. Thậm chí có thể không?

Tôi không chắc chắn nếu sử dụng Provider<T> hoặc một Nhà máy có thể giúp đỡ vì điều đó vượt quá sự hiểu biết của tôi ngay bây giờ, nhưng tôi muốn gợi ý về cách cấu trúc mọi thứ nếu trường hợp đó xảy ra!

EDIT: Cách bạn tạo công việc với Hàng đợi công việc ưu tiên Android. Tôi đã sửa đổi một mẫu để chỉ ra cách tôi muốn tiêm được làm việc. Các công việc được đăng trên onAdded() và deserialized trước khi nó chạy với onRun():

// A job to send a tweet 
public class PostTweetJob extends Job { 

    @Inject MyService webservice; 
    public static final int PRIORITY = 1; 
    private String text; 

    public PostTweetJob(String text) { 
     // This job requires network connectivity, 
     // and should be persisted in case the application exits before job is completed. 
     super(new Params(PRIORITY).requireNetwork().persist()); 
    } 
    @Override 
    public void onAdded() { 
     // Job has been saved to disk. 
    } 
    @Override 
    public void onRun() throws Throwable { 
     // Job logic goes here 
     webservice.postTweet(text); 
    } 
    @Override 
    protected void onCancel() { 
     // Clean up 
    } 
} 
+0

Nói chung, bạn thường sắp xếp từng mô hình/các lớp đơn giản. Tại sao họ thậm chí cần truy cập vào trường hợp Retrofit? Thêm một lớp Manager/Presenter/Handler làm các cuộc gọi Backend và giữ mô hình (lớp serialized của bạn) không có tùy chọn? –

+0

@DavidMedenjak Tôi đã thêm một số mã mẫu để hiển thị những gì xảy ra với Hàng đợi công việc ưu tiên Android. Tôi cần gọi dịch vụ của tôi (hoặc Retrofit) từ công việc khi nó chạy. – snafu109

+1

Readme của thư viện cho thấy rằng có hỗ trợ cho DI bằng cách thêm một vòi phun, bạn đã thử điều đó chưa? Điều này có vẻ như cách sạch nhất để đi –

Trả lời

6

Đây là giải pháp đơn giản nhất mà tôi có thể quản lý.

Trước tiên, hãy tạo lớp học BaseJob. Đây sẽ là mục tiêu tiêm:

public abstract class BaseJob extends Job { 
    // annotate fields that should be injected and made available to subclasses 
    @Inject MyService service; 

    protected BaseJob(Params params) { 
     super(params); 
    } 
} 

Nó tuyên bố abstract do đó không cần phải ghi đè lên bất kỳ phương pháp trừu tượng khai báo trong lớp Job. Thay vào đó, các phương thức sẽ được ghi đè trong các công việc được kế thừa từ BaseJob.

Tạo công việc được kế thừa từ BaseJob. Bất kỳ lĩnh vực tiêm vào BaseJob có sẵn để sử dụng:

public class MyActualJob extends BaseJob { 
    public static final int PRIORITY = 1; 

    public MyActualJob() { 
     super(new Params(PRIORITY).requireNetwork().persist()); 
    } 

    @Override 
    public void onAdded() { 
     // job added to queue 
    } 

    @Override 
    public void onRun() throws Throwable { 
     // do the work 
     // service will be injected into BaseJob, so you can use it here 
     final Call<User> call = service.getUser(); 
     call.execute(); 
    } 

    @Override 
    protected void onCancel() { 
     // clean up 
    } 
} 

Cuối cùng, để đảm bảo mọi thứ được liên kết lên, thêm một DependencyInjector-JobManager khi nó được tạo ra. Này đưa vào công việc của BaseJob:

DependencyInjector dependencyInjector = new DependencyInjector() { 
    @Override 
    public void inject(Job job) { 
     // this line depends on how your Dagger components are setup; 
     // the important part is to cast job to BaseJob 
     ((MyApplication) app).component().inject((BaseJob) job); 
    } 
}; 
Configuration configuration = new Configuration.Builder(getApplicationContext()) 
     .injector(dependencyInjector) 
     .build(); 
JobManager jobManager = new JobManager(getApplicationContext(), configuration); 

Tại sao không bỏ qua sử dụng BaseJob và tiêm trực tiếp vào MyActualJob?Điều này sẽ làm việc, tuy nhiên nếu có một số công việc mà là mục tiêu tiêm, tôi tin rằng bạn sẽ phải sử dụng instanceof để kiểm tra những gì loại công việc đã được tạo ra và đúc job đến lớp đúng khi tạo DependencyInjector:

DependencyInjector dependencyInjector = new DependencyInjector() { 
    @Override 
    public void inject(Job job) { 
     if (job instanceof MyActualJob) { 
      ((MyApplication) app).component().inject((MyActualJob) job); 
     } else if (job instanceof MyRealJob) { 
      ((MyApplication) app).component().inject((MyRealJob) job); 
     } else if (job instanceof MyBetterJob) { 
      ((MyApplication) app).component().inject((MyBetterJob) job); 
     } 
    } 
}; 

Trong trường hợp của tôi, hầu hết nếu không phải tất cả các công việc đều cần quyền truy cập vào cùng một đối tượng toàn cục, vì vậy nó sạch hơn đối với lớp con BaseJob và sử dụng nó làm mục tiêu tiêm duy nhất.

+0

cái này hoạt động! – chip

+0

này, nếu mỗi công việc sử dụng một dịch vụ khác thì sao? Tôi có thể tạo BaseJob cho mỗi công việc không? –

+0

Không, bạn sẽ thêm dịch vụ vào dịch vụ BaseJob: @Inject DifferentService; hoặc thực hiện kiểm tra nếu tuyên bố và tiêm công việc mới – Jessicardo

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