Android--jni play strange part 1

Learn jni development.

Ensure that the AS has installed relevant SDK tools, mainly LLDB, NDK and CMAKE

1. Build a jni project

Create a jni project and select Native C + +,

New is complete.

See what the default generated project has.

1.1 main page MainActivity

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");//Note 1
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());//Note 2
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();//Note 3
}

At note 1, it is declared to load the native lib library.
Note 3 declares the native method.
At note 2, call the native method.

1.2 native-lib.cpp

The project path is in jniapplication \ app \ SRC \ main \ CPP \ native lib cpp .

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_cosmos_jniapplication_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

Method simply returns a string.

1.3 CMakeLists.txt

Automatically generated. Focus on native lib, which is the name of cpp file.

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             native-lib.cpp)

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
                       native-lib

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

Run build and display Hello from C + + according to the expected results.

Unzip the generated apk, and there is libnative lib in the lib directory so .

Referring to the default example, the jni development process is as follows (I understand it, don't spray it if it's wrong):

  • 1. Write cpp documents;
  • 2. In cmakelists Txt, mainly add_library , target_link_libraries ;
  • 3. Load library, declare native method and call in java.

2. Add a new method of your own

The default generated example has an instance. According to the gourd painting ladle, add a method by yourself.

2.1 in native lib Adding methods to CPP

In native lib Adding Java method to CPP_ com_ cosmos_ jniapplication_ MainActivity_ getMaxNum,

Four parameters. env and jobobject are the parameters required by jni syntax, and a and b are the actual parameters. Simply return the maximum values of the two.

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_cosmos_jniapplication_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

extern "C" JNIEXPORT jint JNICALL
Java_com_cosmos_jniapplication_MainActivity_getMaxNum(
        JNIEnv* env,
        jobject,
        jint a,
        jint b
        ){
    return a > b ? a : b;
}

2.2 declare the new method and use it

Because the new method is in native lib In CPP, declare that the step of loading the native lib library has been completed.

Declare the newly added native method and use it,

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
        System.loadLibrary("new-add");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        //tv.setText(stringFromJNI());
        tv.setText(getMaxNum(10,9));//use
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();

    public native int getMaxNum(int a, int b);//statement
}

Run it, it is the expected result. The explanation is correct

3. Add a new library

Come on, go on.

3.1 new cpp

In native lib Create a new add. Directory under CPP peer directory Cpp file.

The old rule is to write with reference to the default example and simply sum.

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jint JNICALL
Java_com_cosmos_jniapplication_MainActivity_getSum(
        JNIEnv *env,
        jobject,
        jint a,
        jint b) {
    return a + b;
}

3.2 CMakeLists.txt to add a new library declaration

Modify cmakelists Txt to add a declaration of the newly added library.

Pay attention to # the comment section of for new add begin, and the name should correspond to

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             native-lib.cpp)

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
                       native-lib

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )
# for new-add begin
add_library( # Sets the name of the library.
        new-add

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        new-add.cpp)
target_link_libraries( # Specifies the target library.
        new-add

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib} )
# for new-add end

3.3 loading, declaration and use

Note 4 declares that the new add library is loaded,
Note 5 declares the native method in the new add library,
Call the method at Note 6.

package com.cosmos.jniapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
        System.loadLibrary("new-add");//Note 4
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        //tv.setText(stringFromJNI());
        //tv.setText(getMaxNum(10,9));
        tv.setText(String.valueOf(getSum(10,20)));//Note 6
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();

    public native int getMaxNum(int a, int b);

    public native int getSum(int a, int b);//Note 5
}

build run, is the desired result.

Unzip the generated apk. Libnew add. Is found in the lib directory so .

Part one, done.

Keywords: Android JNI NDK

Added by derezzz on Fri, 21 Jan 2022 15:33:39 +0200