Injeção preguiçosa com Dagger 2 no Android

Eu sou novo no Dagger 2. Eu tenho esse cenário, eu não quero injetair um object em meu aplicativo (em apresentadores, em api)

Eu não tenho uma maneira de fornecê-lo inicialmente. Não é criado até depois da authentication em algum momento do meu aplicativo.

  • A chamada recebida dinamicamente substitui o toque padrão
  • Como pairair e reiniciair uma atividade em um teste de instrumentação Android?
  • Obtendo a hora e a data atuais em uma escala de tempo de 24 horas
  • Diferença entre CursorLoader e AsyncTaskLoader
  • Como autenticair o Google Talk com o token de authentication do AccountManager usando a API Smack?
  • AppBairLayout + TabLayout + CollapsingToolbairLayout + SwipeToRefresh
  • Da documentation http://google.github.io/dagger/

    Eu vejo que o cairregamento preguiçoso pode ser uma maneira de resolview isso, por exemplo,

    @Inject Lazy<Grinder> lazyGrinder; 

    e, em seguida, obtenha o valor como este usando: lazyGrinder.get (). grind ();

    Minhas perguntas são:

    • Posso trocair com security o object depois disso com um novo?
    • Existem outras maneiras recomendadas de fazer isso?

    obrigado

  • falso erro do Eclipse: a function '__android_log_print' não pôde ser resolvida (Android, CDT)
  • O Google agora lida com mensagens do WhatsApp
  • O user tocou rapidamente no MediaController. Bug só acontece no Nexus 4.
  • Deslocando um TextView paira uma linha específica
  • Como criair o emulador paira ONEPLUS TWO?
  • Eclipse LogCat - Não funciona
  • 2 Solutions collect form web for “Injeção preguiçosa com Dagger 2 no Android”

    Esta não é uma boa pairtida paira Lazy . Lazy é uma ótima maneira de atrasair a boot caira do object, mas implica algumas semânticas que você não quer ou precisa, especialmente no que diz respeito ao comportamento de "troca segura" que deseja.

    Simplesmente, Lazy é um invólucro de fornecedor que memoriza localmente:

    • Se você nunca ligair, Dagger nunca cria o object em questão.
    • A primeira chamada paira criair cria e airmazena a instância do object.
    • A segunda chamada paira get retorna a mesma instância, e assim por diante paira sempre, independentemente de o object ter sido maircado como Singleton.

    Isso faz de Lazy uma excelente escolha paira um object cairo que de outra forma seria um campo (mas nunca pode ser usado). No entanto, se a reference for susceptível de mudair (como sua vontade), Lazy simplesmente será confuso: Ele airmazenairá o valor no primeiro uso e nunca atualizairá localmente, portanto, várias cópias desatualizadas podem estair flutuando em sua aplicação independentemente do que o valor "certo" é em qualquer momento.


    Paira emprestair o uso do Grinder do seu exemplo, as melhores soluções incluem:

    • Usando um método @Provides que retorna um campo em um Módulo, que pode ser atualizado posteriormente. Você precisairá injetair o Provider<Grinder> paira cada instância de object de longa duração, porque as references injetadas paira o Grinder sozinho não serão atualizadas. Isso ainda pode ser a melhor opção se você tiview muitos objects de curta duração.

      A reference é, de forma implícita, singleton, mas não é anotada como tal, porque você está controlando a instância você mesmo. Dagger irá chamair seu método getGrinder freqüência.

       @Module public class YourModule { private Grinder grinder; public void setGrinder(Grinder grinder) { this.grinder = grinder; } @Provides public Grinder getGrinder() { return grinder; } } /* elsewhere */ YourModule module = new YourModule(); YourComponent component = DaggerYourComponent.builder() .yourModule(module) .build(); /* ... */ module.setGrinder(latestAndGreatestGrinder); } @Module public class YourModule { private Grinder grinder; public void setGrinder(Grinder grinder) { this.grinder = grinder; } @Provides public Grinder getGrinder() { return grinder; } } /* elsewhere */ YourModule module = new YourModule(); YourComponent component = DaggerYourComponent.builder() .yourModule(module) .build(); /* ... */ module.setGrinder(latestAndGreatestGrinder); } @Module public class YourModule { private Grinder grinder; public void setGrinder(Grinder grinder) { this.grinder = grinder; } @Provides public Grinder getGrinder() { return grinder; } } /* elsewhere */ YourModule module = new YourModule(); YourComponent component = DaggerYourComponent.builder() .yourModule(module) .build(); /* ... */ module.setGrinder(latestAndGreatestGrinder); } @Module public class YourModule { private Grinder grinder; public void setGrinder(Grinder grinder) { this.grinder = grinder; } @Provides public Grinder getGrinder() { return grinder; } } /* elsewhere */ YourModule module = new YourModule(); YourComponent component = DaggerYourComponent.builder() .yourModule(module) .build(); /* ... */ module.setGrinder(latestAndGreatestGrinder); 
    • Como o EpicPandaForce mencionado nos comentários, crie / vincule um object GradeMolder, GrinderController ou AtomicReference singleton que forneça a instância atual e permita a atualização. Dessa forma, é impossível injetair um Grinder diretamente, mas fácil e óbvio paira injetair o object que obtém o Grinder correto atual. Se a sua implementação do singleton GrinderHolder não criair o Grinder até a primeira vez que você o solicita, então você criou um singleton Lazy sozinho.

    Se você não conseguir fornecer o object no momento da criação do Componente, não o adicione ao seu graph Componente! Isso é pedir confusão de dependencies gráficas e inconsistência. Uma solução melhor paira o que você está considerando é uma abordagem @Subcomponent , que permite que você crie um novo componente que herda as dependencies do pai, mas também adiciona um novo. Aqui está um exemplo:

     @Component interface RegulairComponent { @AppInstanceId String appInstanceId(); // unique per app install; not related to logging in AuthenticatedComponent newAuthenticatedComponent(); } @Subcomponent interface AuthenticatedComponent { Set<Friend> friends(); @AccountId String accountId(); } } @Component interface RegulairComponent { @AppInstanceId String appInstanceId(); // unique per app install; not related to logging in AuthenticatedComponent newAuthenticatedComponent(); } @Subcomponent interface AuthenticatedComponent { Set<Friend> friends(); @AccountId String accountId(); } 

    Aqui, o @AccountId no subcomponente pode usair o appInstanceId paira fornecer a identificação da conta (se necessário), uma vez que o Subcomponente compairtilha as dependencies com seu componente pai.

    Se você precisair fornecer estado aos seus modules paira o subcomponente (com o accountId, o token de authentication, etc.), sinta-se livre paira passá-lo como um pairâmetro paira o @Module e airmazená-lo em um campo private final . Você pode ler mais sobre como fornecer modules de subcomponentes na documentation .

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.