• Ramon Ferreira Silva

Injeção de Dependências no Android

Atualizado: 22 de Ago de 2019


Logo do Android

Android e Injeção de Dependências


Eu considero a injeção de dependências crucial para qualquer código OO, e em se tratando de Aplicativos Android a injeção é interessante não somente para injeção de coisas como Services, mas também com injeção de Views ( e Fragments ).


A injeção de dependências também permite aumentar a testabilidade do seu código, quando por exemplo você pode facilmente trocar uma dependência de objeto por um Mock.


A injeção de Dependências não é apenas sobre testes, mas muito além. Ela provê um melhor reuso e intercâmbio de módulos por toda a sua aplicação. Também permite mudar o objeto  a ser injetado conforme o ambiente, usando por exemplo um

DevLoggongModule em desenvolvimento e um ProdLoggingModule em Produção.


Usando o Dagger


Fazendo uma rápida pesquisa na web, a maioria dos resultados apontam para o Dagger como sendo a melhor opção. O Dagger é um projeto Open Source da Square, uma empresa que faz muitas coisas legais e de graça para o Android.


O Dagger é um biblioteca bem leve de injeção de dependências que implementa o padrão Java para anotações JSR-300 como @Inject e @Singleton.


O Dagger constrói instancias da classes de sua aplicação e satisfaz as suas dependências usando a Anotação javax.inject.Inject para identificar quais construtores ou campos estamos interessados.


Usando a anotação @Inject no construtor o Dagger irá criar uma nova instancia de objeto, e quando esta instancia for requisitada, o Dagger irá obter os parâmetros necessários e invocar o construtor.

class Usuario {
	
	
	private final Perfil perfil;

	@Inject
	public Usuario(Perfil perfil){
	    this.perfil = perfil;
	}

}

Mas você pode querer injetar os campos diretamente, para isso basta anotar os atributos da classe.

class Usuario {
	
	@Inject
	Perfil perfil;

	@Inject
	Endereco endereco;

	public Usuario(){
		
	}

}

Satisfazendo as Dependências


Por padrão o Dagger satisfaz todas as dependências de objetos que você requisitar. Se você pedir uma nova instancia de carro, então o objeto carro será chamada pelo seu construtor os campos anotados serão injetados, retornando um objeto completo.

Porém o Dagger não funciona em algumas situações.

  1. Não Constrói Interfaces.

  2. Classes de Terceiros não pode ser anotadas.

  3. Objetos Configurados devem ser configurados pode você mesmo.

Para esses casos onde o @Inject é insuficiente ou inoperante, use a anotação @Provides.

Todos os métodos anotados com @Provides devem estar dentro de uma classe @Module.


@Module
class ApplicationModule{ 
   @Provides 
   pubic Perfil providePerfil() {
      return new PerfilUsuarioPremium();
   }

   @Provides 
   pubic Usuario providesUsuario(Perfil perfil) {
      return new Usuario(perfil);
   }
}

Por convenção usa-se o prefixo provide no nome de cada método provedor e o sufixo Module em cada classe de módulo.


Usando em uma aplicação Android


As suas classes de módulos precisam ser inicializadas e injetadas dentro de um ObjectGraph. O melhor local para realizar esta tarefas é em uma classes Application customizada.

public class Application extends android.app.Application {

    private ObjectGraph objectGraph;

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

       objectGraph = ObjectGraph.create(new ApplicationModule());
    }

    public ObjectGraph getObjectGraph() {
        return objectGraph;
    }
}

Para poder injetar em suas activities como dependências, você precisará invocar o método inject do objeto ObjectGraph.

public abstract class BaseActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ((Application) getApplication()).getObjectGraph().inject(this);
    }
}

Depois de feito isso suas activities estão prontas para serem injetadas em qualquer outro objeto.

public class MainActivity extends BaseActivity {

    @Inject
    Usuario mUsuario;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mUsuario.facaAlgo(...);
    }
}

O Dagger possui muitas funcionalidades a mais que essas, e você pode conferir no site do Desenvolvedor.


#CódigoLimpo #SOLID #Refatoração #injeçãodedependências #Boas #Android

0 visualização