Como usar o punhal? Como configurar o Dagger para funcionar no meu projeto Android?
Eu gostaria de usar o Dagger em meu projeto Android, mas acho confuso.
EDIT: Dagger2 também está disponível desde 2015 04 15, e é ainda mais confuso!
[Esta pergunta é um "esboço" que estou adicionando à minha resposta à medida que aprendo mais sobre Dagger1 e aprendo mais sobre Dagger2. Esta questão é mais um guia do que uma "questão".]
android
dependency-injection
dagger
dagger-2
EpicPandaForce
fonte
fonte
ViewModel
ePageKeyedDataSource
? Como eu uso RxJava2 e quero que CompositeDisposable seja compartilhado por ambas as classes e se o usuário pressionar o botão Voltar, quero limpar o objeto Disposable. Eu adicionei um caso aqui: stackoverflow.com/questions/62595956/…ViewModel
e talvez passar o mesmo compositeDisposable como o argumento do construtor do seu PageKeyedDataSource personalizado, mas eu não usaria Dagger para essa parte porque você precisa de subcomponentes sub-escopo, e o Hilt não fará suporte para isso fácil para você.Respostas:
Guia para Dagger 2.x (edição revisada 6) :
As etapas são as seguintes:
1.) adicionar
Dagger
aos seusbuild.gradle
arquivos:.
.
2.) Crie sua
AppContextModule
classe que fornece as dependências.3.) criar a
AppContextComponent
classe que fornece a interface para obter as classes que são injetáveis.3.1.) É assim que você criaria um módulo com uma implementação:
Cuidado: Você precisa fornecer a
@Scope
anotação (como@Singleton
ou@ActivityScope
) no@Provides
método anotado do módulo para obter um provedor com escopo dentro do componente gerado, caso contrário, ele ficará sem escopo e você obterá uma nova instância cada vez que injetar.3.2.) Crie um componente com escopo de aplicativo que especifique o que você pode injetar (é o mesmo
injects={MainActivity.class}
em Dagger 1.x):3.3.) Para dependências que você mesmo pode criar através de um construtor e não quer redefinir usando um
@Module
(por exemplo, você usa tipos de compilação para alterar o tipo de implementação), você pode usar o@Inject
construtor anotado.Além disso, se você usar o
@Inject
construtor, poderá usar a injeção de campo sem ter que chamar explicitamentecomponent.inject(this)
:Essas
@Inject
classes construtoras são adicionadas automaticamente ao componente do mesmo escopo, sem a necessidade de especificá-las explicitamente em um módulo.Uma classe de construtor com
@Singleton
escopo definido@Inject
será vista nos@Singleton
componentes com escopo definido.3.4.) Depois de definir uma implementação específica para uma determinada interface, como:
Você precisará "vincular" a implementação específica à interface com um
@Module
.Uma abreviação para isso, uma vez que Dagger 2.4, é o seguinte:
4.) crie uma
Injector
classe para lidar com seu componente de nível de aplicativo (substitui o monolíticoObjectGraph
)(nota:
Rebuild Project
para criar aDaggerApplicationComponent
classe builder usando APT)5.) crie sua
CustomApplication
classe6.) adicionar
CustomApplication
ao seuAndroidManifest.xml
.7.) Injetar suas aulas em
MainActivity
8.) Aproveite!
+1.) Você pode especificar
Scope
seus componentes com os quais pode criar componentes com escopo no nível de atividade . Os subescopos permitem fornecer dependências que você precisa apenas para um determinado subescopo, em vez de em todo o aplicativo. Normalmente, cada atividade obtém seu próprio módulo com esta configuração. Observe que existe um provedor com escopo por componente , ou seja, para reter a instância dessa atividade, o próprio componente deve sobreviver à mudança de configuração. Por exemplo, ele pode sobreviver através deonRetainCustomNonConfigurationInstance()
, ou uma mira de morteiro.Para mais informações sobre subcopagem, confira o guia do Google . Consulte também este site sobre métodos de provisionamento e também a seção de dependências de componentes e aqui .
Para criar um escopo personalizado, você deve especificar a anotação do qualificador de escopo:
Para criar um subescopo, você precisa especificar o escopo em seu componente e especificar
ApplicationComponent
como sua dependência. Obviamente, você também precisa especificar o subescopo nos métodos do provedor de módulo.E
Observe que apenas um componente com escopo pode ser especificado como dependência. Pense nisso exatamente como a herança múltipla não é suportada em Java.
+2.) Sobre
@Subcomponent
: essencialmente, um escopo@Subcomponent
pode substituir uma dependência de componente; mas em vez de usar um construtor fornecido pelo processador de anotação, você precisaria usar um método de fábrica de componentes.Então, é isso:
Torna-se isto:
E isto:
Torna-se isto:
+3.): Por favor, verifique outras questões sobre Stack Overflow relacionadas a Dagger2 também, elas fornecem muitas informações. Por exemplo, minha estrutura Dagger2 atual é especificada nesta resposta .
obrigado
Obrigado pelos guias do Github , TutsPlus , Joe Steele , Froger MCS e Google .
Também para este guia de migração passo a passo que encontrei depois de escrever este post.
E para explicação de escopo por Kirill.
Ainda mais informações na documentação oficial .
fonte
DaggerApplicationComponent
é gerado automaticamente pelo APT na construção, mas vou adicioná-lo.Guia para Dagger 1.x :
As etapas são as seguintes:
1.) adicionar
Dagger
aobuild.gradle
arquivo para as dependênciasAlém disso, adicione
packaging-option
para evitar um erro sobreduplicate APKs
.2.) criar uma
Injector
classe para lidar com oObjectGraph
.3.) Crie um
RootModule
para vincular seus módulos futuros. Por favor, note que você deve incluirinjects
para especificar cada classe em que você usará@Inject
anotações, caso contrário, Dagger lançaRuntimeException
.4.) No caso de você ter outros submódulos dentro de seus módulos especificados em seu Root, crie módulos para estes:
5.) criar os módulos folha que recebem as dependências como parâmetros do construtor. No meu caso, não havia dependência circular, então não sei se Dagger pode resolver isso, mas acho improvável. Os parâmetros do construtor também devem ser fornecidos em um Módulo por Dagger; se você especificar
complete = false
, ele também pode ser fornecido em outros Módulos.6.) Estenda
Application
e inicialize oInjector
.7.) Em seu
MainActivity
, chame o Injetor noonCreate()
método.8.) Use
@Inject
em seuMainActivity
.Se você receber o erro
no injectable constructor found
, certifique-se de não esquecer as@Provides
anotações.fonte
Android Bootstrap
. Portanto, os créditos a eles por descobrirem isso. Usos de soluçãoDagger v1.2.2
.dagger-compiler
deve serprovided
diferente, ele será incluído no aplicativo e está sob licença GPL.