Thursday, July 7, 2022
HomeWeb DevelopmentIntegrating a Rust module into an Android app

Integrating a Rust module into an Android app


Since I’ve expertise in cross-compiling and constructing automation, I typically select Rust as my main programming language. As well as, Rust remains to be a comparatively new language, and using any know-how from the earlier decade is setting you as much as fail. Generally, following the hype practice is the quickest path to success.

If you’d like one among your challenge’s promoting factors to be that customers can management their very own knowledge, you possibly can’t use a very browser-based service. As an alternative, you’d have to ship one thing that buyers can function on their very own Android units. If you have already got some headless situations working internally, with just a bit extra effort, you possibly can develop redistributable packages for Home windows and Linux.

Nonetheless, needless to say solely having a desktop model of the app could be a major roadblock. If you’d like your app to essentially take off, you’d additionally want a cell model. Due to this fact, you might want to work out find out how to make your app work on Android.

This GitHub repo, which has a primary, built-in Reverse Polish Notation calculator, demonstrates integrating a Rust module into an Android app. Nonetheless, our challenge, which is able to seem like the picture beneath, will use a extra low-level strategy, immediately utilizing the C and Rust compilers. All points associated to cross-compilation, like compiler flags, linker flags, and extra, are addressed explicitly.

We use Gradle primarily to assemble every part into an .apk bundle. In case you’re in search of a fast and easy answer, you need to use a Rust plugin for Gradle to significantly simplify the process. Let’s get began!

Rust Module Android Example

Desk of contents

Stipulations

First, we’ll cowl a few of the required instruments and platforms wanted for our challenge implementation. You’ll want:

  • Android Native Growth Package r21
  • GCC
  • Bash
  • Android Software program Growth Package

You may get the Android instruments from the Android Developer portal. Solely the SDK is required, not the complete Android Studio set up. Make sure you get the r21 LTS launch of the NDK, not the latest r22 launch.

Rust with cross-compilers

First, set up Rust with rustup-init. As soon as Rust is put in, use rustup to put in help for Android targets. To start, you’ll have to receive the Rust cross-compilers. Fortunately, Rust makes this very simple by calling the next:

rustup goal add aarch64-linux-android
rustup goal add armv7-linux-androideabi
rustup goal add x86_64-linux-android

Java runtime surroundings

Our instance challenge makes use of Gradle to generate the .apk, which requires a JRE to run. Whereas Android Studio gives you with the choice to obtain and specify a JRE and Gradle to run with it, this challenge makes use of your system’s default, JRE.

Surroundings variables

You’ll additionally want Android improvement instruments. Regardless of its 80+ MB measurement, the SDK bundle incorporates the minimal required instruments, so you possibly can make the most of the SDK supervisor so as to add the really helpful extras. Obtain the command-line instruments archive from the Android Studio downloads web page.

Whereas Android can run native code, most apps are written in Java or Kotlin, as mirrored within the SDK. Lastly, to work with native code, you’ll want the Native Growth Package. There are quite a few variations of the NDK obtainable for obtain on the NDK downloads web page, however as talked about beforehand, we’ll wish to use the r21 model.

Lastly, arrange the surroundings variables proven beneath earlier than beginning a construct:

  • ANDROID_SDK_ROOT: Factors to the Android SDK listing
  • ANDROID_NDK_ROOT: Factors to the Android NDK r21 listing
  • ANDROID_API: Specifies the Android API degree you wish to goal, i.e., 29

Directories

The main listing incorporates scripts used to finish the construct and tie it collectively.

android/

The android/ listing contains the Android app recordsdata, the AndroidManifest.xml file, exercise with a rudimentary UI, and glue courses for interacting with the Rust code.

rust/

We’ll maintain our Rust code within the rust/ folder. It’s divided into three sections:

  • android.rs
  • lib.rs
  • foremost.rs

The app might be constructed as a standalone executable, which is able to learn enter from stdin one line at a time, consider it, and output the end result.

Constructing the applying and actions

To grasp find out how to mix Rust code with the Java code, which gives the consumer interface, you possibly can analysis “find out how to mix Rust code APK with Java code”. Off the bat, you’ll seemingly discover that it isn’t simply doable with out understanding Android apps. A minimum of, not in a clear and easy matter.

Most articles counsel a distinct strategy: integrating the actions right into a single software:

bundle pl.martin.weblog.RustOnAndroid;

import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Shade;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
        personal Button button;
        personal EditText enter;
        personal TextView resultBox;

        personal int colourRed;
       personal int colourGreen;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
               tremendous.onCreate(savedInstanceState);
               setContentView(R.format.activity_main);

                button = (Button)findViewById(R.id.button);
                enter = (EditText)findViewById(R.id.exprInput);
                resultBox = (TextView)findViewById(R.id.exprResult);

                colourRed = Shade.parseColor("#AA0000");
                colourGreen = Shade.parseColor("#007F00");

                button.setOnClickListener(new View.OnClickListener() {
                        public void onClick(View v) {
                                String expr = enter.getText().toString();
                                End result end result = RpnCalculator.rpn(expr);
                                if(end result.isOk()) {
                                        resultBox.setTextColor(colourGreen);
                                        resultBox.setText(end result.getValue());
                                } else {
                                        resultBox.setTextColor(colourRed);
                                        resultBox.setText(end result.getError());
                                }
                        }
                });
        }
}

In case you’ve by no means handled Android earlier than, exercise is what you’d contemplate a display or view whilst you’re creating your app. For instance, contemplate a procuring app. Some actions often is the login display and the checkout cart.

Some interactive elements, like the enduring hamburger menu, could also be included. You possibly can theoretically put the complete program in a single exercise should you needed to, however this might be troublesome to implement. After all, there’s extra to debate about actions, however that isn’t the main focus of this text.

Now, let’s return to our Rust software. Whereas integrating actions into one software appeared the answer to my dilemma, I wasn’t positive how my Rust.apk match into all of this. After poking round within the cargo-apk code, I found that it wraps my code in some magic glue code and generates a NativeActivity for Android to run.

You’ll have to tamper with AndroidManifest.xml and add an exercise node to the doc to unite the actions into one app. When cargo-apk completes its activity, it creates a small AndroidManifest.xml file and saves it alongside the ultimate APK. You should utilize this file to search out out what properties the NativeActivity has.

Go forward and add the code beneath to the Java app’s manifest:

<?xml model="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        bundle="pl.martin.weblog.RustOnAndroid">

        <software
                android:allowBackup="true"
                android:icon="@mipmap/ic_launcher"
                android:label="@string/app_name"
                android:roundIcon="@mipmap/ic_launcher_round"
               android:supportsRtl="true"
             android:theme="@type/Theme.RustOnAndroid">
             <exercise android:title="pl.martin.weblog.RustOnAndroid.MainActivity">
                     <intent-filter>
                                <motion android:title="android.intent.motion.MAIN" />

                                <class android:title="android.intent.class.LAUNCHER" />
                       </intent-filter>
                </exercise>
        </software>

</manifest>

The Java app’s construct course of is not going to mechanically work out the place your libstartup.so file is included. You must copy the library recordsdata to a specific listing, the place Gradle, the Android app’s construct mechanism, would mechanically detect them. Doing so added a declaration to the app’s manifest stating that the app will comprise sure actions:

$ mkdir -p android/app/src/foremost/jniLibs/arm64-v8a
$ cp sqlite-autoconf-3340000/.libs/libsqlite3.so android/app/src/foremost/jniLibs/arm64-v8a/
$ cp goal/aarch64-linux-android/debug/libstatup.so android/app/src/foremost/jniLibs/arm64-v8a/
$ cd android/ && ./gradlew && ./gradlew construct

After that, begin the construct. You’ll see that it’s working, so you possibly can set up the .apk in your Android smartphone.

Finishing the construct

To finish the process, use the build-all.sh script. It should save the ensuing .apk recordsdata subsequent to this script within the construct/ listing. You’ll construct GMP and Rust code as nicely:

build-libgmp.sh

The script above is used for creating the GMP library solely:

build-librpn.sh

This script is used to generate Rust code solely. Word that you need to first create GMP and the .so recordsdata. GMP have to be current in LIBS DIR, in any other case, linking will fail:

build-apk.sh

Create solely the .apk file utilizing the script above. It’s important first to create GMP and the Rust code. The app will compile with out native libraries, however it’s going to crash when it’s run.

Conclusion

It wasn’t simple getting our Rust code to function on Android, however we discovered the answer. We wrote our code in commonplace Rust, then compiled it to a shared library, which the JVM then loaded at runtime. Whereas the JNI first appeared horrifying, using this standardized methodology meant that neither the Java code nor the Gradle construct system was vital as a result of we wrote the native code in Rust.

Cross-compiling with Cargo was nonetheless a problem as a result of we needed to configure many environmental variables with cargo-apk to make all of it work. There was additionally a problem with exterior libraries that our code relied upon, however we solved all of this with just a few shell scripts.

Be at liberty to take a look at the GitHub repository on find out how to combine a Rust module into an Android app. I hope you loved this text, and make sure you go away a remark in case you have any questions. Glad coding!

LogRocket: Full visibility into manufacturing Rust apps

Debugging Rust functions might be troublesome, particularly when customers expertise points which can be troublesome to breed. In case you’re serious about monitoring and monitoring efficiency of your Rust apps, mechanically surfacing errors, and monitoring sluggish community requests and cargo time, attempt LogRocket.

LogRocket is sort of a DVR for net and cell apps, recording actually every part that occurs in your Rust app. As an alternative of guessing why issues occur, you possibly can mixture and report on what state your software was in when a problem occurred. LogRocket additionally displays your app’s efficiency, reporting metrics like shopper CPU load, shopper reminiscence utilization, and extra.

Modernize the way you debug your Rust apps — .

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments