Injeção de dependência no Android usando Hilt | Joe Rakhimov | Skillshare

Velocidade de reprodução


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Injeção de dependência no Android usando Hilt

teacher avatar Joe Rakhimov

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Aulas neste curso

    • 1.

      Boas-vindas

      0:47

    • 2.

      Exemplo

      1:45

    • 3.

      Dependência

      1:22

    • 4.

      Injeção de dependência

      2:28

    • 5.

      Localizador de serviços

      2:11

    • 6.

      Dagger e Hilt

      1:01

    • 7.

      Programar

      0:57

    • 8.

      Sem injeção de dependência

      3:02

    • 9.

      Com injeção de dependência

      2:41

    • 10.

      Fluxo de trabalho Hilt

      1:52

    • 11.

      ViewModel

      1:31

    • 12.

      Ligações

      2:34

    • 13.

      Singleton

      1:08

    • 14.

      CONTEXTO

      1:07

    • 15.

      Nomeado

      1:21

    • 16.

      Qualificador

      0:57

    • 17.

      Componente

      3:13

    • 18.

      Obrigada

      0:38

  • --
  • Nível iniciante
  • Nível intermediário
  • Nível avançado
  • Todos os níveis

Gerado pela comunidade

O nível é determinado pela opinião da maioria dos estudantes que avaliaram este curso. Mostramos a recomendação do professor até que sejam coletadas as respostas de pelo menos 5 estudantes.

15

Estudantes

--

Projetos

Sobre este curso

Você está se perguntando qual é a injeção de dependência e dependência, por que você precisa de injeção de dependência em seu projeto e como implementá-la usando Hilt? Então você está no lugar certo e este curso é para você.

Neste curso, você vai aprender a:

  • quais são a injeção de dependência e dependência

  • como implementar injeção de dependência usando Hilt

  • diferentes recursos da biblioteca Hilt

Injeção de dependência é uma técnica importante para criar código:

  • Mais sustentável

  • Evite replicação de código

  • Melhore o gerenciamento de ciclo de vida

  • Mais testável

  • Mais legível

Hilt é uma biblioteca de injeção de dependência que é construída em cima do Dagger e ajuda a implementar a injeção de dependência sem um monte de código de placa de caldeira.

No final do curso, você será capaz de:

  • configure a biblioteca Hilt no projeto Android Studio

  • criar um módulo para fornecer dependências

  • fornecer dependências usando anotação @Forneça

  • vincule dependências usando anotação @Binds

  • injetar dependências usando anotação @Inject

  • integre o Hilt no ViewModel

  • para fornecer a mesma instância com anotação @Singleton

  • injetar um texto usando Hilt

  • fornecer instâncias dos mesmos tipos usando anotações @Named e @Qualifier

Implementação de injeção de dependência é demonstrada no exemplo de um aplicativo de previsão meteorológica simples. Depois de fazer este curso, você será capaz de implementar Injeção de dependência usando Hilt em seu projeto Android Studio.

Conheça seu professor

Teacher Profile Image

Joe Rakhimov

Professor
Level: All Levels

Nota do curso

As expectativas foram atingidas?
    Superou!
  • 0%
  • Sim
  • 0%
  • Um pouco
  • 0%
  • Não
  • 0%

Por que fazer parte da Skillshare?

Faça cursos premiados Skillshare Original

Cada curso possui aulas curtas e projetos práticos

Sua assinatura apoia os professores da Skillshare

Aprenda em qualquer lugar

Faça cursos em qualquer lugar com o aplicativo da Skillshare. Assista no avião, no metrô ou em qualquer lugar que funcione melhor para você, por streaming ou download.

Transcrições

1. Boas-vindas: Bem-vindo ao curso de injeção de dependência no Android usando o Health. Meu nome é Garrett ou Hue. Estou desenvolvendo aplicativos para Android desde 2013. Neste curso, você aprenderá o que é dependência, por que ela pode ser um problema e como resolver esse problema usando a injeção de dependência. Você aprenderá como implementar a injeção de dependência usando uma biblioteca chamada hilt. Além disso, criaremos aplicativo simples de previsão do tempo usando o hilt. Para fazer este curso, você deve estar familiarizado com o desenvolvimento do Android. Vamos usar a linguagem de programação Kotlin. Além disso. Você deve ter o Android Studio instalado em sua máquina. Se você estiver pronto, vamos começar o curso. 2. Exemplo: Vamos começar o curso com um exemplo rápido de dependência e injeção de dependência. Aqui vou mostrar um exemplo de dependência. Esta é a classe do motor. Possui função de partida que faz com que o motor dê partida. E temos a classe Car, que cria uma instância do motor. E tem função de partida que imprime que o carro está dando partida e liga o motor. Também temos a função principal, onde criamos instância do carro e começamos. O problema é que aqui, nesta linha, estamos criando instâncias de motor dentro do carro. Nesse caso, motor é dependência. O carro depende do vidro do motor. Como podemos resolver esse problema? Isso pode ser resolvido. Movendo-se, criando uma instância fora do dependente, nós a movemos para a função principal e passamos uma instância para o carro. Agora estamos analisando o mecanismo de instância no carro usando seu construtor. Isso é chamado de injeção de dependência. Vamos executar esse código e ver o resultado. O código está funcionando. E esse foi um exemplo rápido do que é dependência e injeção de dependência. 3. Dependência: Neste vídeo, veremos o que é dependência. dependência acontece quando um componente depende de outro componente. Por exemplo, uma classe depende de outra classe. Neste exemplo, estamos criando instâncias de motor dentro do carro. Então, o carro depende do motor. Nesse caso, o carro é dependente, o antígeno é dependência. Você pode dizer quais podem ser os problemas com a dependência. O primeiro problema é chamado de replicação. Estamos criando um mecanismo de instância dentro do carro. Portanto, talvez precisemos criar essas instâncias em muitos lugares. Isso resulta na replicação do código. Outro problema é a facilidade de manutenção. Imagine a situação os construtores de motores funcionam em cadeias. Portanto, precisamos alterar o código em todos os lugares em que estamos criando instâncias do mecanismo. Outro problema é o gerenciamento do ciclo de vida. Aqui estamos criando exemplos de motor dentro do carro. Isso significa que quando o carro é removido, o motor também é removido. Esses problemas podem ser resolvidos usando injeção de dependência. 4. Injeção de dependência: Neste vídeo, veremos o que é injeção de dependência. injeção de dependência está criando e injetando dependência. Neste exemplo, estamos criando uma instância do motor na função principal e passando a função construtor de dois carros. E isso é chamado de injeção de dependência. A injeção de dependência resolve problemas com dependência. É a replicação do código-fonte criando dependência em um só lugar. Neste exemplo, estamos criando instâncias do motor na função principal e passando para o objeto do carro. Se precisarmos alterar sua função construtora, precisamos alterar o código em um só lugar. Portanto, isso melhora a capacidade de manutenção do código. injeção de dependência resolve o problema com o gerenciamento do ciclo de vida. Aqui estamos criando instâncias de motor e objeto de carro que passa. Portanto, quando o carro é removido e não removido , temos controle sobre o ciclo de vida. Existem três tipos de injeção de dependência: injeção construtor, campo e método. Como vimos no exemplo anterior, dependência é criada e passada para a função construtora. Isso é chamado de injeção de construtor. Esse tipo é preferido , pois podemos tornar dependência privada para torná-la imutável. Outro tipo é a injeção cheia. Nesse caso, injetamos dependência no campo. Este tipo de injeção é usado quando o construtor não está disponível. O exemplo é o sistema Android. Não temos controle sobre os componentes do Android como atividade, fragmento etc. Outro tipo é a injeção de método. Esse tipo de injeção é usado quando não temos controle sobre o construtor. E queremos injetar várias dependências ao mesmo tempo. 5. Localizador de serviços: Neste vídeo, falaremos sobre o localizador de serviços. Existem duas maneiras de resolver o problema de dependência. A primeira forma é a injeção de dependência, em que as dependências são injetadas no dependente. Para implementar a injeção de dependência, podemos usar a biblioteca curada. Outra forma de resolver o problema de dependência é a pesquisa de dependências, em que as dependências são recuperadas de fora. chamado localizador de serviços, que retorna dependências pelo nome. Deixe-me mostrar um exemplo de localizador de serviços. Aqui temos um motor de vidro com estrela de função que imprime que o motor está dando partida. Aqui temos um objeto chamado localizador de serviços, que cria uma instância do mecanismo e da função, que retorna dependências pelo nome. exemplo, ele retorna a instância do mecanismo quando o nome é igual a dois mecanismos. Se o nome não for encontrado, ele gera uma exceção de argumento ilegal com dependência de mensagem com a seguinte chave que não foi encontrada na classe car. instância do mecanismo é recuperada do localizador de serviços usando a função de pesquisa com a chave do mecanismo. Em seguida, a função de partida imprime o carro que está dando partida e liga o motor. Na função principal, criamos a instância do motor e a chamamos de função de partida. O localizador de serviços é um padrão projetado que dá acesso ao objeto por seu nome. Ele permite criar objetos em um só lugar e obtê-los por seus nomes. Ele resolve o problema de dependência criando uma instância em um só lugar. Portanto, não há aplicação de código. Também cria dependência externa. Portanto, a mudança na dependência não resulta em mudança no dependente. Além disso, o ciclo de vida da dependência não está vinculado ao ciclo de vida do dependente. O localizador de serviços é usado por uma biblioteca chamada coin, que está fora do escopo deste curso. 6. Dagger e Hilt: Dagger and a dagger é uma biblioteca de injeção de dependência, que facilita a implementação da injeção de dependência. Ele reduz muito código padronizado ao implementar a injeção de dependência. Q também é uma biblioteca de injeção de dependência, que é construída sobre uma adaga e facilita o uso da adaga. Como funciona. O Dagger usa o processador de anotações para analisar o código, identificar onde injetar dependências e quais tipos de dependências são necessárias. Em seguida, o dagger gera o código-fonte que é compilado pelo compilador. Aqui está a biblioteca de injeção de dependência, que é construída em cima de uma adaga. Ele permite escrever menos código com contêineres predefinidos para classes Android e também facilita a injeção de dependências no modelo de visualização e a injeção do próprio modelo de visualização. 7. Programar: O código deste curso está disponível no seguinte URL. Se você abrir esse URL, poderá encontrar um repositório de código no GitHub, que contém código para aplicativo simples de previsão do tempo. Para clonar esse repositório, clique em Código, clique aqui para copiar o URL e abrir o Android Studio. No Android Studio, clique em Arquivo. Novo projeto a partir do controle de versão. Aqui, cole o URL que copiamos. E aqui você deve definir o diretório em que deseja salvar o projeto e clicar em Clonar. Depois de clonar o código, você pode executar esse aplicativo em seu dispositivo ou emulador. 8. Sem injeção de dependência: Neste vídeo, mostrarei código sem injeção de dependência. Vamos abrir o Android Studio. Já clonamos o código do repositório. E agora estamos na filial principal. Precisamos dar uma olhada em nenhuma agência de DI. Essa ramificação contém código sem injeção de dependência. Em primeiro lugar, vamos abrir o AndroidManifest.xml. Aqui podemos ver que ele tem uma permissão para conexão com a Internet, usa texto não criptografado. O tráfego é enviado para poder usar a conexão HTTP. E temos uma tela chamada Previsão de atividade. Na atividade de previsão, estamos criando instâncias de modernização usando o URL base. E estamos configurando nossa fábrica de conversores JSON para converter dados JSON em objeto. No final, estamos criando uma instância da interface da API. No método onCreate, estamos definindo um layout XML como visualização de conteúdo. Vamos abri-lo. Aqui temos uma visualização do reciclador para mostrar os dados de previsão. Então, estamos chamando método de previsão do jato para obter a previsão do tempo. No método de previsão de jatos, estamos criando uma corrotina para obter a previsão do tempo. E então estamos trocando dois despachantes principais para mostrar a previsão do tempo. No método de previsão resumida, estamos definindo o nome do local como título e, em seguida, verificando se os dados diários da previsão estão disponíveis. Se não for nulo, estamos configurando o gerenciador de layout para a visualização do reciclador. E então estamos configurando o adaptador de previsões. O adaptador recebe dados de previsão e os define de acordo com o layout, que é a previsão do item da lista. Ele contém três, leva dois anos para mostrar a data, temperatura e condição. Na compilação do Gradle, foram adicionadas dependências de arquivos para retrofit e retrofit e dishonor conversores . Vamos abrir a interface da API. E inclui uma função que retorna previsões, respostas, campanhas de resposta e informações diárias atuais de localização para os dados da previsão. Agora, vamos executar esse aplicativo e ver o resultado. Aqui você pode ver o aplicativo que mostra nome do local no título e os dados da previsão do tempo como uma lista. 9. Com injeção de dependência: Neste vídeo, veremos código com injeção de dependência. No vídeo anterior, vimos código sem injeção de dependência, onde criamos uma instância de API na atividade de previsão. Portanto, a API é dependência e a previsão da atividade é dependente. Agora vamos mudar para uma ramificação chamada DI, que contém código com injeção de dependência. Para usar essa biblioteca, ela deve ser adicionada ao projeto. Deixe-me mostrar como ele foi adicionado. Em primeiro lugar, vamos abrir o arquivo build gradle. Aqui podemos ver que o plug-in para a biblioteca de HIV foi adicionado. Vamos abrir o arquivo Build Gradle para o módulo do aplicativo. E o plug-in para sua biblioteca foi aplicado. Além disso, precisamos adicionar o processador de anotações Kotlin para usar a biblioteca heal. Certifique-se de que o projeto use o Java 1.8, pois a recuperação exige. Em seguida, adicionamos dependência para a biblioteca recuperada. E adicionamos isso para permitir que as referências gerem código. próxima etapa é criar uma classe chamada App, que estende o aplicativo e aplicativo Android curado anotado. Essa anotação faz com que o heel gere um código de injeção de dependência. Abra o AndroidManifest.xml e declare o aplicativo usando o atributo name. Dentro do pacote IP, criamos uma classe de módulo que é anotada com as anotações instaladas e do módulo. Dentro deste módulo, criamos função que é anotada com provides patient e fornece uma instância de API que será injetada na atividade de previsão. A atividade de previsão é anotada com ponto de entrada do Android para injetar dependências nela. Aqui estamos injetando a instância de um cara com a anotação Inject. Portanto, não o estamos criando dentro da atividade de previsão. Agora, vamos executar esse código e ver o resultado. Aqui podemos ver o mesmo aplicativo, mas desta vez implementamos a injeção de dependência. 10. Fluxo de trabalho Hilt: Neste vídeo, mostrarei como a saúde funciona. Vamos começar com a classe AP, que estende o aplicativo e usa a anotação recuperada do aplicativo Android. anotação indica aqui que é necessário gerar código de injeção de dependência , incluindo um único componente. O componente Singleton é um contêiner de dependência em nível de aplicativo, que injeta dependências. Na classe App Model, estamos usando a anotação do módulo para dizer a ele que o módulo do aplicativo fornece dependências instaladas na anotação e é usado para dizer a qual componente o módulo do aplicativo fornece dependências. Nesse caso, um módulo fornece dependências para o componente único, que é um contêiner de dependência em nível de aplicativo. O módulo App fornece dependência como instância da API usando fornece anotação. Na atividade de previsão, a anotação do ponto de entrada do Android é usada para criar o componente de atividade, que é filho do componente único. Portanto, isso significa que o componente de atividade da atividade de previsões tem acesso às dependências do componente único. Usando a anotação Inject, podemos injetar uma instância da API. O fluxo de trabalho geral parece que esse módulo de aplicativo fornece uma instância de API para um único componente. componente de atividade da atividade de previsão tem acesso às dependências de um único componente e injeta dependências na instância da API usando a anotação Inject. 11. ViewModel: Neste vídeo, mostrarei como injetar dependências no modelo de visualização. Em primeiro lugar, vamos abrir módulos, criar um arquivo gradle e adicionar dependência às extensões do Kotlin para artefatos de atividades. Dentro do modelo de visualização de previsão, criamos LiveData mutáveis para resposta à previsão. E criamos o LiveData, que será observado pela previsão da atividade. Quando o modelo de previsão é inicializado. No entanto, o método de previsão é chamado. O método de previsão cria uma corrotina, que é limpa. Quando esse modelo de visualização é limpo. Insights é o escopo da corrotina. Obtemos os dados da previsão e atualizamos o LiveData mutável. Na atividade de previsão, injetamos modelo de visualização da previsão não usando a anotação Inject, mas usando a API do provedor ViewModel. Caso contrário, teríamos várias instâncias do modelo de visualização. Aqui, definimos o observador para dados de previsão do tempo, que chama mostrar o método de previsão em Atualizar. Agora, vamos executar esse aplicativo e ver o resultado. Como você pode ver, está funcionando. Mas, desta vez, estamos obtendo dados no modelo de visualização em vez da atividade. 12. Ligas: Neste vídeo, mostrarei como usar a anotação de vínculos. Agora, criamos um repositório de dados, que serve como uma única fonte de dados. Para isso, criamos uma interface chamada repositório com uma função, get forecast. É a função de suspensão que retorna a resposta da previsão. Criamos uma classe chamada repository impulse, que é a implementação da interface do repositório. E recebe uma instância de API para implementar o método get forecast. Na classe do módulo app, criamos uma função que fornece uma instância de implementação do repositório quando o repositório é solicitado. Não é aqui que estamos obtendo uma instância da API e usando o buscador para a implementação do repositório. Nos vídeos anteriores, usamos anotação provides para fornecer dependência. Mas neste vídeo, eu gostaria de mostrar outra forma de fornecer dependência. Para isso, criamos outro módulo que fornece dependências para o componente singleton. E, nesse caso, usamos o saneamento básico para fornecer dependência. Aqui, criamos uma nova função que fornece instância de implementação do repositório quando o repositório é solicitado. Quando usamos o saneamento de estacas, a implementação da função é fornecida pelo cabo. Na implementação do repositório, permitimos que esse trecho de código seja capaz de injetar API quando usamos o saneamento de vínculos implementação da função é fornecida pela saúde. É por isso que precisamos usar a anotação Inject na função construtora para injetar a instância da API. Na previsão do seu modelo, injetamos repositório em vez de API, que serve uma única fonte de dados. Agora, vamos executar esse aplicativo e ver o resultado. Como podemos ver, está funcionando da mesma maneira. Mas desta vez usamos repositório como uma única fonte de dados. E também usamos saneamento embutido para limitar a dependência. 13. Singleton: Neste vídeo, mostrarei como fornecer a mesma instância quando a dependência for solicitada. O módulo fornece dependências para o componente único e cria instâncias sempre que a dependência é solicitada. Para verificar isso, podemos injetar uma instância da API e fazer o login como uma string. Fazemos a mesma coisa no repositório na classe em massa. Agora vamos executar esse código e ver o resultado. Você se sente aberto, logcat, podemos ver que as instâncias da API não são iguais. Para criar um módulo para retornar a mesma instância toda vez que podemos usar a anotação singleton. Essa anotação diz ao healed que crie apenas uma instância no contêiner de dependência de componente único. Agora vamos executar esse código e ver o resultado. Desta vez, podemos ver que as instâncias são iguais. 14. CONTEXTO: Neste vídeo, mostrarei como injetar contexto. Em primeiro lugar, precisamos adicionar dependência para o interceptor http, o verificador de cores. No módulo do aplicativo, criamos uma instância do interceptor de chakra, que requer contexto. Podemos obter contexto usando a anotação de contextos de aplicativos. Em seguida, injetamos o interceptor de chocolate na função onde criamos uma instância de um cliente HTTP OK. Em seguida, fornecemos um cliente HTTP para uma função na qual criamos uma instância de modernização. Agora, vamos executar esse código e ver o resultado. Depois de executar, abra a gaveta de navegação e clique na notificação, que diz que gravar é atividade GTP. E aqui podemos ver a lista de solicitações que foram enviadas para o back-end. 15. Nomeado: Neste vídeo, mostrarei como fornecer instâncias do mesmo tipo com o nome de uma anotação. Em primeiro lugar, abra o arquivo Gradle construído pelos módulos e adicione dependência para o interceptor de registro HTTP. Essa biblioteca registra solicitações HTTP no logcat. Em seguida, abra a classe do módulo e adicione a função, que fornece outro interceptor de login. E agora estamos fornecendo duas instâncias ao mesmo tempo. Interceptador. Quando injetamos dependência, calcanhar deve saber qual instância gostaríamos de injetar. Para este propósito, a anotação denominada é usada. Aqui estamos definindo a anotação name it com a chave interceptora de login. Para o interceptor Tucker, estamos usando nome e anotação com a chave interceptora http. Quando estamos obtendo essas instâncias, devemos usar a mesma anotação com a mesma chave. E aqui estamos configurando interceptores HTTP para o cliente HTTP. Agora vamos executar esse aplicativo e ver o resultado. Agora, podemos ver o log de solicitações HTTP no logcat. 16. Qualificador: Neste vídeo, mostrarei outra maneira de fornecer instâncias do mesmo tipo usando anotações personalizadas. No arquivo do módulo do aplicativo, criamos duas anotações personalizadas usando a anotação qualificadora. Usando a anotação de retenção, fazemos com que essa anotação seja armazenada na saída binária. E criamos anotações, interceptor http e interceptor de login. Aqui, fornecemos instâncias de interceptor usando anotações personalizadas em vez de anotação de ID de nome. Além disso, substituímos a anotação nomeie uma anotação personalizada quando obtemos essas instâncias. Agora, vamos executar esse aplicativo e ver o resultado. E podemos ver o mesmo resultado, registro de solicitações HTTP no logcat. 17. Componente: Neste vídeo, falaremos sobre componentes. Uma das vantagens da biblioteca curada é que ela contém componentes predefinidos. Os componentes são contêineres de dependência que injetam dependências. Cada componente está vinculado a algum ciclo de vida no aplicativo Android. Aqui podemos ver a hierarquia dos componentes e o componente principal é o componente único. Ele está disponível em toda a aplicação. Ele é criado quando o aplicativo é criado, é destruído quando o aplicativo é destruído. O mesmo se aplica a outros componentes, por exemplo, componente de atividade é criado quando a atividade é criada e destruída. Quando a atividade é destruída. Isso é útil quando precisamos de dependência apenas em uma atividade, não em todo o aplicativo. De acordo com essa hierarquia, as dependências do componente singleton estão disponíveis para o componente de atividade, mas as dependências do componente de atividade não estão disponíveis para o componente único ou outros componentes, como componente ViewModel , porque é um componente irmão. Anotação acima, cada componente é usado para fornecer uma única instância de dependência, por exemplo , anotação singleton para componente único ou anotação de escultura de atividade é usada para componente de atividade. Vamos criar um novo módulo que fornece dependências para o componente de atividade. Em primeiro lugar, abra os módulos at, construa o arquivo Gradle e adicione dependência para a biblioteca Picasso. É usado para carregar a imagem. Em seguida, no XML de previsão do item da lista, adicionamos um novo ImageView para mostrar o ícone da condição climática. Em seguida, criamos uma nova interface chamada carregador de imagens, que tem uma função para carregar a imagem do URL nas imagens. Depois disso, criamos a implementação do carregador de imagens chamado Picasso image loader, e ele implementa a função de carregamento de imagem usando a biblioteca Picasso. Depois disso, criamos um novo modelo chamado módulo de atividade, que fornece dependências. Para o componente de atividade. Ele tem uma função e fornece , portanto, carregador de imagens, quando o carregador de imagens é solicitado. Aqui estamos usando a anotação de escultura de atividade para usar uma instância do carregador de imagens. Na atividade de previsão, estamos injetando o carregador de imagens e passando para o adaptador de previsões. No adaptador de previsão, pegamos esse carregador de imagens e o usamos para carregar a imagem do URL no ImageView. Vamos executar esse código e ver o resultado. Como podemos ver agora, ele está mostrando ícones para previsões e condições meteorológicas. 18. Obrigada: Este é o final deste curso onde você aprende o que é dependência e injeção de dependência. Você aprenderá como configurar o healed para implementar a injeção de dependência usando diferentes futuros de hailed. Como bônus, gostaria de fazer perguntas de entrevista sobre injeção de dependência e cura. É um arquivo PDF com perguntas e respostas e você pode baixá-lo na seção de recursos deste vídeo. Eu gostaria de agradecer a você por assistir a este curso. Espero que tenham gostado e nos vemos nos meus próximos cursos.