If you’re like me, you love to code but hate dealing with Java. Well, good news! You can still write native C++ code and use it in your Android app without having to learn a single line of Java.
First, let’s create our project. Open up your favorite IDE (I prefer IntelliJ) and create a new Android project. Make sure you select “Empty Activity” as the template. This will give us a blank slate to work with.
Now that we have our project set up, it’s time to add our native library. To do this, go ahead and download your favorite C++ library (I recommend Boost) from their website. Once you have the source code, extract it somewhere on your computer.
Next, let’s create a new folder in our project called “jni”. This is where we will put all of our native code. Inside this folder, create another folder called “src” and copy over the Boost header files into it (you can find them in the source code you downloaded earlier).
Now that we have our headers set up, let’s write some C++ code! Create a new file inside your jni/src directory called “mylibrary.cpp”. Inside this file, add the following:
“`c++
// Include necessary header files
#include
#include
#include
// Declare the function as an external C function
extern “C” {
// Declare the function as a JNI export with appropriate parameters and return type
JNIEXPORT jstring Java_com_example_mylibrary_MyLibrary_reverseString(JNIEnv* env, jobject instance, jstring input) {
// Convert the jstring input into a C-style string
const char *cstr = env->GetStringUTFChars(input, 0);
// Convert the C-style string into a C++ string
std::string str(cstr);
// Use the boost library’s string reversal function to reverse the string
boost::algorithm::reverse(str.begin(), str.end());
// Convert the reversed string back into a jstring and return it
return env->NewStringUTF(str.c_str());
}
}
This code defines a function called "reverseString" that takes in a Java string, reverses it using the Boost library, and returns the result as a new Java string.
Now let's create our Android class to call this native function. Go ahead and open up your MainActivity.java file. Inside the onCreate method, add the following:
java
// This function takes in a Java string, reverses it using the Boost library, and returns the result as a new Java string.
public void reverseString(View view) {
// Get the input string from the editText view and convert it to a Java string.
String input = editText.getText().toString();
try {
// Get the Java Native Interface (JNI) environment.
JNIEnv *env = getJNIEnv();
// Call the static object method “myReverseStringMethodID” from the “myLibrary” library, passing in the input string as a UTF-8 encoded string.
jstring result = (jstring) env->CallStaticObjectMethod(myLibrary, myReverseStringMethodID, env->NewStringUTF(input));
// Convert the result from a JNI string to a Java string.
String reversed = env->GetStringUTFChars(result, 0);
// Set the textView to display the reversed string.
textView.setText(reversed);
} catch (Exception e) {
// If an error occurs, log it to the console.
Log.e(“MainActivity”, “Error calling native function: “, e);
}
}
This code calls our native function and displays the result in a TextView.
Finally, let's add some boilerplate to make this work. In your MainActivity.java file, add the following at the top of the class:
java
// Declaring a private static final variable “TAG” with a value of “MainActivity” to be used as a tag for logging purposes
private static final String TAG = “MainActivity”;
// Declaring a private static final variable “MY_LIBRARY” with a value of “com/example/mylibrary” to be used as the package name for our native function
private static final String MY_LIBRARY = “com/example/mylibrary”;
// Declaring a private static final variable “REVERSE_STRING” with a value of “reverseString” to be used as the name of our native function
private static final String REVERSE_STRING = “reverseString”;
// Declaring a private static final variable “JNI_VERSION” with a value of 1 to be used as the version number for our native function
private static final int JNI_VERSION = 1;
// Declaring a private static variable “myReverseStringMethodID” to be used as a reference to our native function
private static MethodId myReverseStringMethodID;
This code defines some constants for our library and function name.
Now let's add the following to your onCreate method:
java
// This code defines the name of our library and function
final String MY_LIBRARY = “myLibrary”;
final String REVERSE_STRING = “reverseString”;
// Load the native library
System.loadLibrary(MY_LIBRARY);
// Override the onCreate method
@Override
protected void onCreate(Bundle savedInstanceState) {
// Call the super class method
super.onCreate(savedInstanceState);
// Set the content view to our main activity layout
setContentView(R.layout.activity_main);
// Declare variables for our library and function IDs
Library myLibrary;
Method myReverseStringMethodID;
// Load the native library and get our function IDs
try {
// Load the library and assign it to our variable
myLibrary = System.loadLibrary(MY_LIBRARY);
// Get the class for our library
Class> clazz = Class.forName(“com.example.mylibrary”);
// Get the method ID for our reverseString function
myReverseStringMethodID = clazz.getDeclaredMethodId(REVERSE_STRING, “()Ljava/lang/String;”);
} catch (Exception e) {
// If there is an error, log it
Log.e(TAG, “Error loading native library: “, e);
}
}
“`
This code loads our native library and gets the function ID for our reverseString method.
And that’s it! You now have a fully functional Android app with a native C++ library. Enjoy your newfound freedom from Java!