2015-10-12 40 views
5

當我嘗試在實現類中注入接口時,總是收到空指針異常。這裏是我的代碼:Dagger 2 - 在實現類中注入接口 - 「嘗試在空對象引用上調用接口方法」

獲取:

空指針錯誤在行LoginManagerImpl類:
@覆蓋
公共字符串getLoginResponse(字符串請求){
回報networkManager.getLoginResponse(請求) ;
}

這裏NETWORKMANAGER總是空,你可以請看代碼。

下面是我的源代碼:

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(); 
} 

回答

4

有兩種方式供您讓匕首注入像networkManager字段依賴性爲LoginManagerImpl

  1. 標註它的構造與@Inject和改變providesLoginManager(Context)

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

    這將意味着匕首將提供LoginManagerImpl,和你的@Provides方法結合LoginManager了這一點。

  2. 如果你想在自己providesLoginManager(Context)實例LoginManagerImpl,然後還要求MembersInjector<LoginManagerImpl>,並用它來注入領域,如networkManager

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

對於你的榜樣,我建議選擇1# 。使用MembersInjector對於不能讓Dagger實例化的類非常有用,例如Android Activities。

0

現場注入不是自動的。您需要通過構造函數提供這些依賴項,或者您需要在構造函數中手動啓動字段注入。

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(); 
} 

或者你必須爲他們提供構造函數參數列表上

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

我能夠加入android:name="my_application_class_name"在AndroidManifest文件的應用程序標籤來糾正錯誤。

相關問題