2015-10-12 9 views
5

Ich erhalte immer eine Nullzeigerausnahme, wenn ich versuche, die Schnittstelle in der Implementierungsklasse zu injizieren. hier ist mein Code:Dolch 2 - Injizierende Schnittstelle in der Implementierungsklasse - "Versuch, Interfacemethode für eine Nullobjektreferenz aufzurufen"

Anfahrt:

Nullpointer Fehler in LoginManagerImpl Klasse an der Linie:
@Override
public String getLoginResponse (String Anfrage) {
return networkManager.getLoginResponse (Anfrage) ;
}

hier Networkmanager ist immer null, können Sie den Code schauen Sie in bitte.

Unten ist mein Quellcode:

public class LoginActivity extends Activity { 

    @Inject 
    NetworkManager networkManager; 

    @Inject 
    LoginManager loginManager; 

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

     loginManager.getLoginResponse("valid Login Request"); 
    } 
} 

public interface NetworkManager 
{ 
    String getLoginResponse(String request); 
    String getUserDetailResponse(String request); 
    String getABCResponse(String request); 
} 

public interface LoginManager 
{ 
    String getLoginResponse(String request); 
} 

public class LoginManagerImpl implements LoginManager { 
    @Inject 
    NetworkManager networkManager; 

    public LoginManagerImpl(Context context) 
    { 

    } 

    @Override 
    public String getLoginResponse(String request) { 
     return networkManager.getLoginResponse(request); 
    } 
} 

public class NetworkManagerImpl implements NetworkManager { 

    public NetworkManagerImpl(Context context) 
    { 

    } 
    @Override 
    public String getLoginResponse(String request) { 
     return "valid login response fetched from server"; 
    } 

    @Override 
    public String getUserDetailResponse(String request) { 
     return "valid user deails"; 
    } 

    @Override 
    public String getABCResponse(String request) { 
     return "valid ABC request response"; 
    } 
} 

@Module 
public class AppModule { 

    DaggerApplication application; 

    public AppModule(DaggerApplication application) { 
     this.application = application; 
    } 

    @Provides 
    @Singleton 
    DaggerApplication provideDaggerApplication() { 
     return application; 
    } 

    @Provides 
    @Singleton 
    public Context provideApplicationContext() 
    { 
     return application.getApplicationContext(); 
    } 

    @Provides 
    @Singleton 
    public LoginManager providesLoginManager(Context context) 
    { 
     return new LoginManagerImpl(); 
    } 

    @Provides 
    @Singleton 
    public LoyaltyCardManager providesLoyaltyCardManager(Context context) 
    { 
     return new LoyaltyCardManagerImpl(context); 
    } 

    @Provides 
    @Singleton 
    public NetworkManager providesNetworkManager(Context context) 
    { 
     return new NetworkManagerImpl(context); 
    } 
} 

@Singleton 
@Component(
     modules = { 
       com.dagger.component.AppModule.class 
     }) 
public interface ApplicationComponent { 
    void inject (LoginActivity activity); 

    NetworkManager getNetworkManager(); 
    LoginManager getLoginManager(); 
} 

Antwort

4

Es gibt zwei Möglichkeiten für Sie Dagger zu lassen Abhängigkeiten injizieren, wie die networkManager Feld in LoginManagerImpl.

  1. Beschriften Konstruktor mit @Inject und ändern providesLoginManager(Context) zu

    @Provides @Singleton 
    LoginManager providesLoginManager(LoginManagerImpl manager) { 
        return manager; 
    } 
    

    Das Dagger bedeutet das LoginManagerImpl liefern und Ihre @Provides Methode bindet LoginManager darauf.

  2. Wenn Sie LoginManagerImpl sich in providesLoginManager(Context) instanziiert wollen, dann fordern auch eine MembersInjector<LoginManagerImpl> und verwenden Sie es Felder wie networkManager zu injizieren:

    @Provides @Singleton 
    LoginManager providesLoginManager(Context context, MembersInjector<LoginManagerImpl> membersInjector) { 
        LoginManagerImpl manager = new LoginManagerImpl(context); 
        membersInjector.injectMembers(manager); 
        return manager; 
    } 
    

Für Ihr Beispiel würde ich Option # 1 empfehlen . Die Verwendung von MembersInjector ist sehr nützlich für Klassen, die nicht von Dagger instanziiert werden können, wie Android-Aktivitäten.

0

Die Feldinjektion erfolgt nicht automatisch. Sie müssen diese Abhängigkeiten entweder über den Konstruktor bereitstellen oder Sie müssen die Feldinjektion im Konstruktor manuell initiieren.

public class LoginActivity extends Activity {  
    @Inject 
    NetworkManager networkManager; 

    @Inject 
    LoginManager loginManager; 

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

     loginManager.getLoginResponse("valid Login Request"); 
    } 
} 

public interface NetworkManager 
{ 
    String getLoginResponse(String request); 
    String getUserDetailResponse(String request); 
    String getABCResponse(String request); 
} 

public interface LoginManager 
{ 
    String getLoginResponse(String request); 
} 

public class LoginManagerImpl implements LoginManager { 
    @Inject 
    NetworkManager networkManager; 

    public LoginManagerImpl(Context context) {  

     ((DaggerApplication)context).getApplicationComponent().inject(this); 
    } 

    @Override 
    public String getLoginResponse(String request) { 
     return networkManager.getLoginResponse(request); 
    } 
} 

public class NetworkManagerImpl implements NetworkManager { 

    public NetworkManagerImpl(Context context) 
    { 
     ((DaggerApplication)context).getApplicationComponent().inject(this);  } 
    @Override 
    public String getLoginResponse(String request) { 
     return "valid login response fetched from server"; 
    } 

    @Override 
    public String getUserDetailResponse(String request) { 
     return "valid user deails"; 
    } 

    @Override 
    public String getABCResponse(String request) { 
     return "valid ABC request response"; 
    } 
} 

@Module 
public class AppModule { 

    DaggerApplication application; 

    public AppModule(DaggerApplication application) { 
     this.application = application; 
    } 

    @Provides 
    @Singleton 
    DaggerApplication provideDaggerApplication() { 
     return application; 
    } 

    @Provides 
    @Singleton 
    public Context provideApplicationContext() 
    { 
     return application.getApplicationContext(); 
    } 

    @Provides 
    @Singleton 
    public LoginManager providesLoginManager(Context context) 
    { 
     return new LoginManagerImpl(); 
    } 

    @Provides 
    @Singleton 
    public LoyaltyCardManager providesLoyaltyCardManager(Context context) 
    { 
     return new LoyaltyCardManagerImpl(context); 
    } 

    @Provides 
    @Singleton 
    public NetworkManager providesNetworkManager(Context context) 
    { 
     return new NetworkManagerImpl(context); 
    } 
} 

@Singleton 
@Component(
     modules = { 
       com.dagger.component.AppModule.class 
     }) 
public interface ApplicationComponent { 
    void inject(LoginManagerImpl loginManagerImpl); 
    void inject(NetworkManagerImpl networkManagerImpl); 
    void inject (LoginActivity activity); 

    NetworkManager getNetworkManager(); 
    LoginManager getLoginManager(); 
} 

Oder Sie haben sie bieten auf Konstruktorargument Liste

@Provides 
    @Singleton 
    public LoginManager providesLoginManager(Context context, NetworkManager networkManager) 
    { 
     return new LoginManagerImpl(context, networkManager); 
    } 
0

konnte ich den Fehler beheben, indem Hinzufügen android:name="my_application_class_name" zur Anwendung Tag in AndroidManifest Datei.