2016-05-16 28 views
5

Jestem nowy w sztyletie i mój wtrysk konstruktora/metody nie działa. Nie działa, co oznacza, że ​​wstrzyknięte pola są nadal wymagane.Android: Dagger 2 i wtrysk konstruktora

To jest mój kod:

@Module 
public class AppContextModule { 

    private final Context appContext; 

    public AppContextModule(Context appContext) { 
     this.appContext = appContext; 
    } 

    @Singleton 
    @Provides 
    public Context getAppContext() { 
     return appContext; 
    } 

} 

@Singleton 
@Component(modules = {AppContextModule.class}) 
public interface MyComponent { 

    void inject(ActivitiesLifeCycleListener obj); 

    void inject(WebViewManager obj); 

    Context context(); 

} 

public final class MyClass { 

    private final WeakReference<Context> mAppContext; 

    @Inject 
    public MyClass(Context context) { 
     this.mAppContext = context 
    } 

} 

public class MyActivity extends BaseActivity { 

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

     MyClass my = new MyClass(); // The IDE requests context! 

    } 

} 

„MojaKlasa” wciąż wymaga „Kontekst”, chociaż użyłem „@Inject” adnotacji powyżej konstruktora. Czego mi brakuje?

Czy muszę nawet ujawnić mój kontekst?

Dzięki.

+0

Jaki jest sens @inject, jeśli zamierzasz utworzyć instancję 'MyClass my = new MyClass();' like this? –

Odpowiedz

10

Cóż ... zadeklarować konstruktor

public MyClass(Context context) { 
    this.mAppContext = context 
} 

a następnie wywołać go bez żadnych parametrów

MyClass my = new MyClass(); // The IDE requests context! 

Dlaczego sądzisz to powinno działać? To jest zwykła Java, nie ma sztyletu i próbujesz utworzyć jakiś nowy obiekt bez dostarczania argumentów.


Dagger ma magii, która zmienia sposób działania java. Aby użyć wstrzyknięcia konstruktora, musisz użyć Sztyletu do wstrzyknięcia twoich pól.

public class MyActivity extends BaseActivity { 

    @Inject 
    MyClass mMyClass; // mark field for injection 

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

     // todo ... create component 

     component.inject(this); // inject fields 
    } 

} 

Zważywszy, że podasz Context gdzieś (dostaniesz błąd Context must be provided... kompilacji, jeśli nie jest) sztylet następnie wstrzyknąć swoją działalność z MyClass przez wywołującegoinject — żadnej magii. Metoda inject przypisze obiekt do twojego pola.


Wtrysk konstruktora oznacza, że ​​nie trzeba używać modułu i uwzględnić metodę dostarczenia obiektu. Nie tylko magicznie tworzy obiekty z powietrza lub zmienia sposób pracy konstruktorów.

+0

możesz mi pomóc na ten temat http://stackoverflow.com/q/43308649/6596724, Dzięki –

+0

Byłoby świetnie, gdybyś pokazał, jak zrobić komponent dla klasy, która nie jest modułem. –