2015-02-25 19 views
8

Đối với làm cho mọi thứ đơn giản, giả sử tôi muốn tiêm EmailValidator từ xác nhận apache vào hoạt động của tôi:Dagger2 - rỗng thay vì tiêm đối tượng

public class MainActivity extends FragmentActivity { 

    @Inject 
    EmailValidator emailValidator; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
    } 

Tôi có một lớp MainModule:

@Module 
public class MainModule { 

    @Provides 
    public EmailValidator providesEmailValidator() { 
     return EmailValidator.getInstance(); 
    } 
} 

và MainComponent giao diện:

@Singleton 
@Component(modules = MainModule.class) 
public interface MainComponent { 

    EmailValidator getEmailValidator(); 
} 

Khi cố gắng sử dụng trình xác thực của tôi trong hoạt động, tôi nhận được giá trị rỗng nter exception:

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean org.apache.commons.validator.routines.EmailValidator.isValid(java.lang.String)' on a null object reference 

Rõ ràng là tôi đang thiếu thứ gì đó. Tôi biết rằng dao găm tạo ra việc triển khai thành phần cho tôi. Tôi có nên sử dụng nó không? Làm sao?

Nếu tôi làm như sau trong phương pháp onCreate của tôi:

 emailValidator = Dagger_MainComponent.create().getEmailValidator(); 

sau đó tất cả mọi thứ hoạt động tốt.

Nhưng tôi muốn có thể sử dụng chú thích @Inject ở bất cứ nơi nào (có thể là trên trình thiết lập/hàm tạo thay vì một trường) thay thế.

Tôi đang thiếu gì?

Tôi đã làm điều tương tự với dagger1 và nó hoạt động. Tất nhiên tôi cần gọi số ObjecGraph.inject(this) trong hoạt động. Tương đương dagger2 là gì?

EDIT:

Ok, vì vậy tôi đã tìm thấy một giải pháp. Nếu ai đó sẽ có một vấn đề như vậy, có một số đoạn:

1) Tôi đã tạo một lớp ứng dụng:

public class EmailSenderApplication extends Application { 

    private MainComponent component; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     component = Dagger_MainComponent 
       .create(); 

     component.inject(this); 
    } 

    public MainComponent component() { 
     return component; 
    } 
} 

2) Trong AndroidManifest.xml:

<application 
     android:name=".EmailSenderApplication" 
     ... 

3) Và cuối cùng, trong lớp hoạt động nơi tôi muốn tiêm một số thành phần hai xấu xí như dòng địa ngục:

component = ((EmailSenderApplication) getApplication()).component(); 
component.inject(this); 
+0

Tôi không thể gọi 'inject' trên thành phần của mình. Cú pháp Dagger_MainComponent dường như đã thay đổi thành DaggerMainComponent. –

Trả lời

9

vẻ như bạn cần phải xây dựng thành phần của bạn như trong:

component = Dagger_ MainComponent.builder() 
     .mainModule(new MainModule()) 
     .build(); 

Thông thường, bạn làm điều này trong các phương pháp onCreate của ứng dụng của bạn, in this fashion.

Một tài nguyên tốt có thể giúp bạn là example apps in the Dagger 2 repo.

Tôi cũng thấy PR hữu ích này, từ một số suggested update to Jake Wharton's u2020 sample app (từ kỹ sư Dagger 2 chính). Nó cung cấp một cái nhìn tổng quan tốt về những thay đổi bạn cần phải thực hiện khi đi từ Dagger 1 đến 2 và, rõ ràng đó là những gì he points people to as well.

+0

Đã thử điều đó, vẫn nhận được một ngoại lệ. – slnowak

+0

Tôi đã tìm ra. Bởi vì các liên kết hữu ích, tôi chấp nhận câu trả lời này :) – slnowak

+0

Vui vì bạn đã sửa nó! Từ các chỉnh sửa của bạn ở trên, có vẻ như bạn đã có trường hợp không có trình xây dựng mô-đun nào của bạn yêu cầu đối số hàm tạo. Khi đó là sự thật, thành phần sẽ có phương thức 'create' để bạn sử dụng thay thế. Rất có thể, sau một thời gian, bạn sẽ cần phải chuyển ứng dụng của bạn vào một trong các mô-đun đó và khi điều đó xảy ra, bạn sẽ phải quay lại sử dụng trình xây dựng như được mô tả ở trên. – gMale

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