Integrando o React Native a um aplicativo nativo Android

Criando uma aplicação Android e integrando com um projeto React Native

Matheus Tadeu
React Brasil
Published in
10 min readSep 9, 2019

--

Créditos da imagem https://bit.ly/2YKseWA

Existem muitas ferramentas para a construção de aplicativos atualmente, mas a maioria delas mesmo tendo a mesma performance de um aplicativo nativo, ou muito próxima, não é possível integrar um aplicativo nativo já existente a um desses frameworks afim de aproveitar as principais vantagens que ele pode te oferecer durante o desenvolvimento do aplicativo.

Já com o React Native apesar de você simplesmente pode criar um aplicativo inteiro usando essa ferramenta com o react-native-cli você, também tem a opção de fazer apenas algumas telas de seu aplicativo nativo, utilizando o React Native aproveitando suas vantagens e com isso, economizando bastante tempo no seu desenvolvimento.

Hoje vamos desenvolver um aplicativo React Native e integrar com um aplicativo nativo Android já existente, onde vai ser possível ir de uma tela com código nativo para outra feita em totalmente com Javascript utilizando alguns pacotes nativos que vão fazer essa conexão.

Vamos iniciar a partir da criação de nosso projeto, para isso irei usar o react-native-cli assim vai ser possível usar o react-native init para iniciarmos o projeto do zero.

react-native init AndroidRNTest

Lembrando que utilizei a versão 0.60.4 do React Native nesse projeto e a partir dessa versão no Android todos os pacotes nativos vão começar, a usar o AndroidX que é a atualização das bibliotecas do Android que são usadas para as funcionalidades de um aplicativo no geral.

Agora que já temos o projeto em React Native já iniciado, vamos criar o aplicativo nativo eu recomendo criar com o mesmo nome, no caso AndroidRNTest para isso é necessário ter o Android Studio instalado e configurado, abrir e clicar e criar um novo projeto que nesse caso vai ser o principal.

Criando o projeto Android

Após clicar em criar um novo projeto essa janela vai ser aberta, para selecionar qual tipo Activity você vai querer iniciar o seu projeto, agora nesse caso vamos utilizar uma Activity vazia

Após selecionar pode clicar em Next e outra janela vai ser aberta, onde você pode colocar o nome do projeto, e editar suas informações só lembrando que como vamos usar o React Native, podemos usar versões do Android a partir da 4.1 que é a versão mínima que é aceita, e também vai ser necessário marcar para fazer utilização do AndroidX pois como já foi dito estamos utilizando a versão 0.60.4 do React Native que agora só vai funcionar com esses novos pacotes. Depois de colocar todas essas informações é só apertar em finish e o projeto vai ser iniciado.

Com o projeto nativo já criado, entre na pasta do projeto em React Native com o mesmo nome AndroidRNTest e após isso entre na pasta android e apague todos os arquivos dentro dessa pasta, depois entre na pasta do projeto nativo que acabou de ser criado e mova todos os arquivos para a pasta android do projeto React Native. Não esquecendo dos arquivos que iniciam com . que muitas vezes podem ficar oculto no gerenciador de arquivos.

Estrutura de pastas do projeto

Todas esses arquivos estão dentro da pasta inicial criada a AndroidRNTest

Outro detalhe é que podemos apagar a pasta com os arquivos nativos de IOS que é gerada quando você cria um projeto React Native

Agora a estrutura do projeto está pronta, e podemos iniciar a configuração do projeto nativo com o React Native fazendo a comunicação na parte nativa.

Configuração

Podemos começar alterando o arquivo build.gradle que está em android/build.gradle no bloco allprojects dentro de repositories adicione esse código:

allprojects {
repositories {
mavenLocal()
jcenter()

maven {
// Android JSC is installed from npm
url("$rootDir/../node_modules/jsc-android/dist")
}

maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}

google()
}
}

Só lembrando que nesse projeto está sendo utilizada a versão 3.4.0 do Gradle do Android como você pode ver abaixo:

dependencies {    ...    classpath 'com.android.tools.build:gradle:3.4.0'    ...
}

Com isso estamos adicionando os pacotes do React Native Android no projeto nativo.

Agora no arquivo build.gradle que está em android/app/build.gradle no começo do arquivo adicione isso:

apply plugin: 'com.android.application'// Adicione essa linha
def useIntlJsc = false

android {
...}

Depois dentro de defaultConfigs que está dentro do bloco android adicione esse código:

android { defaultConfig {   ...    // Adicione isso    ndk {
abiFilters "armeabi-v7a", "x86"
}
}}

No bloco de dependencies desse mesmo arquivo, é necessário adicionar essa verificação de qual versão do JavascriptCore (que para quem não conhece é uma engine Javascript que é usada pelo React Native e também pelo Safari, navegador da Apple) está sendo usada.

Também vai ser necessário adicionar o pacote do React Native que vai nos possibilitar usar as classes necessárias, de código nativo para fazer conexão com a parte em Javascript do aplicativo

dependencies {    // Adicionar essas linhas    if (useIntlJsc) {
implementation 'org.webkit:android-jsc-intl:+'
} else {
implementation 'org.webkit:android-jsc:+'
}

implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
// Adicionar essa linha implementation "com.facebook.react:react-native:+"

}

Ainda no final desse arquivo adicione esse código com uma tarefa do BUCK que é a última alteração desse arquivo

task copyDownloadableDepsToLibs(type: Copy) {
from configurations.compile
into 'libs'
}

E no arquivo android/settings.gradle é necessário no seu começo na primeira linha esse código que diz o nome do seu projeto:

// Adicionar essa linha
rootProject.name = 'AndroidRNTest'
include ':app'

Lembrando que esse nome do projeto adicionado, deve ser o nome do projeto React Native que pode ser encontrado na pasta raíz no arquivo índex.js na função registerComponent do AppRegistry que recebe o nome do seu projeto o appName e um componente principal App

Nas últimas versões do React Native o nome é importado do arquivo app.json que também está localizado na raiz, dentro desse arquivo podemos encontrar o nome do projeto:

{  "name": "AndroidRNTest",
"displayName": "AndroidRNTest"
}

O valor name é o usado como nome do projeto que está no index como já foi dito

Adicionando a integração do React Native

A configuração já está pronta e agora vamos começar a escrever o código das classes que realmente fazem essa integração do código nativo e React Native

Podemos começar criando a MainApplication.java a nossa classe responsável por instanciar o React Native Host que é a classe que faz todas as configurações necessárias para criar uma instância do ReactInstanceManager que como o próprio nome já diz é a classe que gerencia a instância do React que é necessária para iniciar a parte em React Native do aplicativo.

Essa classe deve ser criada no pacote main do projeto, que fica localizado em android/app/src/main/java/<your.package.name> vamos criar a classe dessa forma

Com isso vai ser aberto uma janela com mais informações sobre a classe, e você colocar essas informações:

Essa classe deve ficar dessa forma, caso o seu nome de projeto for outro, preste atenção para não copiar a linha do package e trocar o nome do seu package

Quando você colocar essas linhas na sua classe, algumas coisas podem ficar em vermelho, caso acontecer isso coloque o mouse em cima dessa classe que não foi reconhecida e aperte Alt + Enter para importar o que for necessário.

A MainApplication vai ser o ponto inicial da conexão da aplicação React Native no código nativo, agora vai aparecer que essa classe não é usada mas vamos utilizar sua referência no arquivo AndroidManifest daqui a pouco.

Ainda vai ser necessário criar uma Activity que para quem não conhece são como chamamos as telas de um aplicativo Android mas nesse caso, uma Activity sem layout pois vamos utilizar essa tela, só para chamar a parte em React Native do aplicativo.

Uma Activity no Android é formada por uma classe Java ou Kotlin mais um layout em um arquivo XML nesse caso só vamos criar a classe

Após isso vamos apenas criar um método chamado getMainComponentName que vai retornar o nome do componente principal da parte em React Native no caso o próprio nome do projeto AndroidRNTest ou caso seu projeto estiver com outro nome use o correto.

Essa classe que vai realmente chamar o código Javascript no projeto nativo ou seja, quando essa Activity ser aberta o componente principal da parte em React Native vai ser exibido.

Configurando o arquivo Android Manifest

Agora vamos adicionar as alterações necessárias no arquivo AndroidManifest que para quem não conhece é o arquivo responsável por definir as principais informações do nosso aplicativo, como todas suas telas, qual tela vai iniciar primeiro, o tema do aplicativo e também suas permissões necessárias perante ao aparelho como audio, voz, localização, escrita de arquivos entre outras. Caso queira saber mais sobre a importância desse arquivo e fazer seus ajustes clique nesse link

Vamos começar colocando essas permissões:


<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

A primeira vai nos permitir ter acesso a internet, isso é necessário para fazer o debugger do React Native funcionar da maneira correta.

Já a segunda vai nos permitir sobrepor janelas no aplicativo, isso também é pedido pelo debugger e provavelmente é usado quando temos algum erro no aplicativo durante o desenvolvimento.

Agora dentro da tag application coloque o atributo chamado android:name com o valor .MainApplication

Como já foi dito todas as telas de um aplicativo Android tem uma referência no arquivo Manifest vamos adicionar a Activity que, criamos a ReactActivity dentro da tag Application do arquivo

<activity            
android:name=".ReactMainActivity"
android:label="ReactActivity"
android:configChanges=
"keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize" />

E embaixo da Activity que acabou de ser adicionada, vamos também colocar a Debugger Activity que é necessária pelo debugger do React Native

<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

No final o arquivo AndroidManifest vai ficar dessa forma:

Iniciando o React Native

Agora é quando vamos definir o momento em que vamos iniciar a parte em React Native no aplicativo nativo, como esse é um exemplo vamos adicionar um botão na MainActivity que é a primeira tela exibida quando o aplicativo é iniciado, após clicar nesse botão a ReactActivity será iniciada e vai iniciar a parte em Javascript do aplicativo.

Para adicionar o botão na tela da Activity vai ser necessário ir até o arquivo activity_main.xml que está localizado em android/app/src/main/res/layout/activity_main.xml que é o arquivo de layout e vamos deixar o layout assim:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Go To React Native"
android:onClick="onClick"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

O layout vai ficar com um botão na tela dessa forma:

No botão na propriedade android:onClick está sendo passado o valor onClick assim vamos criar uma função no arquivo MainActivity.java com o nome no caso onClick assim toda vez que o botão for clicado a função vai ser executada.

package com.br.androidrntest;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// Adicionar isso public void onClick(View view) {

Intent i = new Intent(getApplicationContext(), ReactMainActivity.class);

startActivity(i);

}

}

Quando o botão for clicado está sendo utilizado uma Intent que no Android são um mecanismo de troca de mensagens. Uma intent indica a intenção de se fazer alguma coisa, seja enviar uma mensagem para um componente ou iniciar um deles. Nesse caso estamos utilizando para abrir uma Activity com a função startActivity(i) e iniciando a ReactActivity

Agora toda a integração com o React Native está finalizada e podemos iniciar o aplicativo.

Para iniciar o aplicativo primeiro inicie o packager do React Native com react-native start e após isso clique no botão de play do Android Studio para dar build e iniciar o aplicativo

Resultado final 😃

O projeto está disponível nesse repositório no GitHub e qualquer dúvida que tiverem, ou se quiserem acrescentar algo, é só deixar um comentário.

Também não esqueça de me acompanhar nas redes sociais, para a gente trocar aquela ideia

matheustadeu.com

www.linkedin.com/in/matheus-tadeu/

Referências

Muito obrigado pela atenção pessoal e espero que tenham gostado.

--

--