-1

Vote down!

Tutorial: How to package a react app or a static site as an android app.

a cup of java

React is a very nice front-end framework, javascript is nice, but what if you need an android app? Or an iOS app for that matter? You have all read of apps that embed a browser, and in the browser javascript runtime, you'd load a full application, written in react or angular or what have you. Maybe pure javascript. 

In fact, it does not matter which framework for front-end development you'd be using - once you build and generate public/index.html and the related assets, or similar, then you can package that "static website" - only html, javascript and assets - as an android app. 

In this tutorial, we'll do exactly that: we'll package a folder is files with an index.html, that represent a compiled web app, as an apk to be installed on an android device. This tutorial assumes intermediate knowledge of frontend technologies. I'm using a macbook but the commands should be similar across OS's.

A word on which technologies are described here. They are capacitor and electron. I am specifically interested in packaging a static site as an apk app. This means I avoid Ionic - whatever it is, it seems a replacement for, say, bootstrap css or material UI. Here, I am focused on the build pipeline, so none of the application-layer frameworks are considered. In fact, I just have an index.html with <h1>Hello, world!</h1> in it, for testing.

Build the Static Site

Now, we will be spending a bit of time using node, so let's install and bootstrap it. Let's build your pure vanilla react app:

npm run build

This way you will have an assets folder that you can point a WebView at. Now let's install capacitor:

npm install @capacitor/core @capacitor/cli
npx cap init myapp com.example.myapp

Obviously, you should replace the defaults. Then run:

npm install @capacitor/android
npx cap add android
npx cap copy
npx cap open android

You should have android studio installed - it's free, and for android development you seem to need it. So, issuing the last command should have opened the android studio for you.

I had to change/match my gradle versions.

Install Java

I had to install the matching version of java for my gradle:

brew install openjdk@17

^ This took too long, so I downloaded a java from Oracle instead: https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html

See where all your java versions are:

/usr/libexec/java_home -V
which java

And in Android Studio see File -> Project Structure -> SDK Location. I get this outcomes:

  • /Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home
  • /Library/Java/JavaVirtualMachines/jdk-19.jdk/Contents/Home
  • /Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home
  • /Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home
  • /opt/java/jdk/Contents/Home/bin/java
  • /Users/piousbox/Library/Android/sdk

Then, I can link (and verify) the correct java version:

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home
export PATH=$JAVA_HOME/bin:$PATH
java -version

I then set java version 17 in Android Studio, File -> Project Structure -> SDK Location -> JDK Location .

I deleted app/android, and re-run:

npx cap add android
npx cap copy
npx cap open android

I then got this error:

The project is using an incompatible version (AGP 8.7.2) of the Android Gradle plugin. Latest supported version is AGP 7.2.1

So, in android/build.gradle I changed this line:

classpath 'com.android.tools.build:gradle:8.7.2' # before
classpath 'com.android.tools.build:gradle:7.2.1' # after

And run:

cd android
./gradlew tasks
Upgrading and Downgrading Java, SDK, and Gradle versions

I downgraded gradle at android/gradpe/wrapper/gradle-wrapper.properties:

distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip

I downgraded java version in app/capacitor.build.gradle :

android {
  compileOptions {
      sourceCompatibility JavaVersion.VERSION_17
      targetCompatibility JavaVersion.VERSION_17
  }
}

And change android/variables.gradle :

ext {
    minSdkVersion = 35
    compileSdkVersion = 35
    targetSdkVersion = 35
    ...
}

That actually moved me forward, and now I could run:

./gradlew tasks
./gradlew build

This eventually worked. Some of the things I did was:

  • download several versions of java, and use a successful combination of java and gradle versions.

I tried downgrading first, but that failed and I ended up upgrading, from java 17, to java 21. This worked, with compileSdkVersion=35.

  • I also temporarily stopped using android studio

I thought it was required, but it wasn't, and ./gradlew build did the job for me, whereas android studio kept complaining about gradle tasks being undefined. The CLI was easier than the UI of the android studio.

  • versioning is very confusing: java 21, sdkVersion 35, gradle 8.7.2

I sort of lost count of all the versions and eventually plugged the latest ones that GPT told me, as ^ above. I eventually found a combination that worked.

So with this, the android project built, producing an apk. This completed the step as per my requirement, and therefore completed this tutorial. If you're interested, more ReactJs tutorials can be found here and Android tutorials here.

.^.

Related Articles

Please log in to post a comment: