Кинжал не вводит обязательное поле - PullRequest
0 голосов
/ 12 октября 2018

У меня есть приложение, которое извлекает значения поиска типа вперед. Я использую кинжал для внедрения зависимости. Однако кинжал вводит значения для класса активности, но не вводит для других классов

Модули

@Module
public class NetModule {

    String baseURL;

    public NetModule(String baseURL){
        this.baseURL=baseURL;
    }


    @Provides
    @Singleton
    SharedPreferences providesSharedPreferences(Application application) {
        return PreferenceManager.getDefaultSharedPreferences(application);
    }



    @Provides
    @Singleton
    Cache provideOkHttpCache(Application application) {
        int cacheSize = 10 * 1024 * 1024; // 10 MiB
        Cache cache = new Cache(application.getCacheDir(), cacheSize);
        return cache;
    }




    @Provides
    @Singleton
    Gson provideGson(){

        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
        return gsonBuilder.create();
    }


    @Provides
    @Singleton
    OkHttpClient provideOkHttpClient(Cache cache) {
        OkHttpClient.Builder client = new OkHttpClient.Builder();
        client.cache(cache);
        return client.build();
    }


    @Provides
    @Singleton
    Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) {
        Retrofit retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(baseURL)
                .client(okHttpClient)
                .build();
        return retrofit;
    }


    @Provides
    @Singleton
    GetTypeAhead provideRGetTypeAhead( Retrofit retrofit) {
        return retrofit.create(GetTypeAhead.class);

    }




}

Модуль моего приложения

@Module
public class AppModule {

    Application mApplication;

    public AppModule(Application application) {
        mApplication = application;
    }

    @Provides
    @Singleton
    Application providesApplication() {
        return mApplication;
    }
}



my component



@Singleton
@Component(modules={AppModule.class, NetModule.class})
public interface NetComponent {

    void inject(MainActivity dataSource);


}

Компонент приложения MyTopLevel для инициализации кинжала

public class MyApp extends Application {


    private NetComponent netComponent;


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

        // Dagger%COMPONENT_NAME%
        netComponent = DaggerNetComponent.builder()
                // list of modules that are part of this component need to be created here too
                .appModule(new AppModule(this)) // This also corresponds to the name of your module: %component_name%Module
                .netModule(new NetModule("https://typeahead.random.com/"))
                .build();

        // If a Dagger 2 component does not have any constructor arguments for any of its modules,
        // then we can use .create() as a shortcut instead:
        //  mNetComponent = com.codepath.dagger.components.DaggerNetComponent.create();
    }

    public NetComponent getNetComponent() {
        return netComponent;
    }
}

Моя деятельность // здесь di работает нормально

public class MainActivity extends AppCompatActivity {

@Inject
 Retrofit retrofit;

    CompositeDisposable compositeDisposable = new CompositeDisposable();
    private ArrayList<String> arr = new ArrayList<>();
    SearchViewModel searchViewModel;
    AutoCompleteTextView textView;
    ArrayAdapter<String> adapter;


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

        searchViewModel = ViewModelProviders.of(this).get(SearchViewModel.class);


        ((MyApp)getApplication()).getNetComponent().inject(this);

        Observable<String> inputObservable = setUpTextObservable();
        textView= (AutoCompleteTextView) findViewById(R.id.productSearchText);
        adapter = new ArrayAdapter<>(this,
                android.R.layout.simple_dropdown_item_1line);

        Log.v("++++++++++++++++++++++",retrofit.toString());

        compositeDisposable.add(searchTextObserver(inputObservable));

    }

.....}

Myдругой класс // здесь инъекция не работает

public class RemoteDataSource {


    @Inject
    GetTypeAhead getTypeAhead;


    Single<TypeAhead> getTypeAhead(String input){

         return getTypeAhead.getTypeAhead(input).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
  }
}

что я здесь не так делаю.Приведите меня к какой-нибудь ссылке, если у меня нет какой-то концепции

Ответы [ 2 ]

0 голосов
/ 13 октября 2018

Чтобы добавить класс RemoteDataSource в граф, вам нужно добавить аннотацию @Inject в его конструктор и класс анотации с областью действия:

@Singleton
public class RemoteDataSource {

    GetTypeAhead getTypeAhead;

    @Inject
    RemoteDataSource(GetTypeAhead getTypeAhead){
        this.getTypeAhead = getTypeAhead;
    }
    //...
  }
}
0 голосов
/ 12 октября 2018

Если вы используете инъекцию свойства, следуйте следующему шагу.В NetComponent добавить void inject(RemoteDataSource dataSource);

@Singleton
@Component(modules={AppModule.class, NetModule.class})
public interface NetComponent {
    void inject(MainActivity dataSource);
    void inject(RemoteDataSource dataSource);
}

В RemoteDataSource классе определить конструктор и выполнить в нем инжекцию

class RemoteDataSource {
    public RemoteDataSource() {
         NetComponent netComponent = // TODO get your component
         netComponent.inject(this)
    }
}

Дополнительную информацию можно найти в Документация кинжала .

Обратите внимание, что это не лучший способ использовать внедрение свойств на вашем пути.Я советую вам использовать конструктор инъекций, который более подробно описан в обсуждение

...