Dagger 2 - 在实现类中注入接口 - "尝试在空对象引用上调用接口方法"

时间:2015-10-12 11:52:01

标签: android dagger-2

当我尝试在实现类中注入接口时,我总是得到空指针异常。这是我的代码:

获得:

  

LoginManagerImpl 类中的Nullpointer错误行:
  @覆盖
  public String getLoginResponse(String request){
    return networkManager.getLoginResponse(request);
  }

这里 networkManager始终为null ,请您查看代码。

以下是我的源代码:

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

3 个答案:

答案 0 :(得分:6)

有两种方法可以让Dagger将networkManager字段之类的依赖项注入LoginManagerImpl

  1. 使用@Inject注释其构造函数并将providesLoginManager(Context)更改为

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

    这意味着Dagger将提供LoginManagerImpl,而您的@Provides方法会将LoginManagerLoginManagerImpl绑定。

  2. 如果您想在providesLoginManager(Context)中自己实例MembersInjector<LoginManagerImpl>,请同时请求networkManager并使用它来注入@Provides @Singleton LoginManager providesLoginManager(Context context, MembersInjector<LoginManagerImpl> membersInjector) { LoginManagerImpl manager = new LoginManagerImpl(context); membersInjector.injectMembers(manager); return manager; } 等字段:

    MembersInjector
  3. 对于您的示例,我建议选项#1。使用if (angular.isUndefined($scope.showText)) { //do stuff }); 对于你不能让Dagger实例化的类非常有用,比如Android Activities。

答案 1 :(得分:1)

现场注入不是自动的。您需要通过构造函数提供这些依赖项,或者您需要通过组件调用类的成员注入。

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

@Singleton
public class LoginManagerImpl implements LoginManager {
    private final NetworkManager networkManager;

    @Inject
    public LoginManagerImpl(NetworkManager networkManager) {    
        this.networkManager = networkManager;
    }

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

@Singleton
public class NetworkManagerImpl implements NetworkManager {
    @Inject
    NetworkManagerImpl(){
    }

    @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
    DaggerApplication provideDaggerApplication() {
        return application;
    }

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

@Module
public abstract class ManagerModule {    
    @Binds
    abstract LoginManager loginManager(LoginManagerImpl impl);

    @Binds
    abstract LoyaltyCardManager loyaltyCardManager(LoyaltyCardManagerImpl impl);

    @Binds
    abstract NetworkManager networkManager(NetworkManagerImpl impl); 
}

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

    NetworkManager getNetworkManager();
    LoginManager getLoginManager();
}

答案 2 :(得分:0)

我能够通过将 android:name="my_application_class_name" 添加到AndroidManifest文件中的应用程序代码来解决错误。