android studio calls C + + code

Android studio calls C + + code

JNI principle

JNI(Java Native Interface) is called JAVA Native Interface.

Java is a cross platform language. This feature depends on the Java virtual machine, which is written by C/C + +. Adapt to each system and provide various services for the upper Java application through JNI to ensure cross platform.

JNI lookup

During the startup process of Android system, the Kernel is started to create the init process, and then the init process fork is the first process that crosses Java and C/C + +, that is, the Zygote process. During Zygote startup, Android runtime startVm in CPP creates a virtual machine. After the VM is created, start reg is called to complete the JNI method registration in the virtual machine.

How does the Java layer find the corresponding location of the corresponding native code

package android.os;
public final class MessageQueue {
    private native void nativePollOnce(long ptr, int timeoutMillis);
}

Step 1: messagequeue The fully qualified name of Java is Android os. MessageQueue.java, the complete method name is Android os. MessageQueue. Nativepollonce(), the corresponding method name of the native layer is to replace the dot with an underscore, that is, android_os_MessageQueue_nativePollOnce().

Step 2: with the native method, you need to know the file where the native method is located. As mentioned earlier, a large number of JNI methods have been registered when the Android system starts. See androidruntime gRegJNI array of CPP. These registration methods command methods:

register_[Package name]_[Class name]

Then messagequeue The JNI registration method name defined by Java should be register_android_os_MessageQueue does exist in the gRegJNI array, indicating that the JNI registration process is completed during startup. This method is in Android runtime CPP is declared as extern method:

extern int register_android_os_MessageQueue(JNIEnv* env);

Most of these extern al methods are located in the / framework/base/core/jni / directory. In most cases, the naming method of the native file is:

[Package name]_[Class name].cpp
[Package name]_[Class name].h

Tips: / messagequeue under android/os path java ==> android_ os_ MessageQueue. cpp

Open android_os_MessageQueue.cpp file, search android_os_MessageQueue_nativePollOnce method, which finds the target method:

static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj, jlong ptr, jint timeoutMillis) {
    NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
    nativeMessageQueue->pollOnce(env, obj, timeoutMillis);
}

This completes the process of searching the corresponding C + + method from the Java layer method.

Android studio calls c++

Build process

First, create a Native C + + project

You will find that the IDE automatically generates a series of files for us. Here are some key documents

In app/src/java, the storage point is java source code. app/src/cpp stores c + + source code

There are cmakelists under the cpp directory Txt file, which contains the rule settings generated by the dynamic library.

add_library( # Sets the name of the library.
        jin_text

        # Sets the library as a shared library.
        SHARED

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

The project build and gradle under app are as follows

plugins {
    id 'com.android.application'
}

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.example.jin_text"
        minSdk 23
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags '-std=c++11'
            }
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    externalNativeBuild {
        cmake {
            path file('src/main/cpp/CMakeLists.txt')
            version '3.18.1'
        }
    }
    buildFeatures {
        viewBinding true
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

Plugiuns are plug-ins used. There are usually two

  • ‘com. android. 'application' indicates that the module is an application module, which can be run directly. What is obtained by packaging is apk file
  • ‘com. android. 'Library' indicates that the module is a library module, which can only be run as a code library attached to other application modules. What is obtained by packaging is aar file

android is a closure. Configure various properties of the item

The specific closure function can be Baidu itself.

Implementation remote dependency declaration.

After that, you only need to write JNI interface (you can use javah) to generate, and then you can call C + + code.

Gradle

Gradle is the framework of an architecture Project. What really works is the plugin. There are two main objects in gradle: Project and Task. Where Project provides the context for the Task. Gradle scripts are written in groovy.

The construction of Gradle consists of one or more projects. Each project can be built as you want, such as web application, jar package, etc.

Each projext is composed of multiple Tasks, and each task represents an atomic operation (compilation, packaging, etc.) in the construction process

Gradle's execution is divided into two phases

  1. In the configuration phase, read all build Gradle to configure project s and task s.
  2. Execution phase
  • Gradle for each build Gradle will create a corresponding Project domain object. When writing gradle script, we are actually operating gradle domain objects such as Project. In a multi Project project, we will operate multiple Project domain objects. Gradle provides powerful multi Project build support.
  • To create a gradle Project with multiple projects, we first need to add settings in the Root Project Gradle's configuration file, which should contain the names of each sub Project. Projects in gradle can be simply mapped to modules in AndroidStudio.
  • In the outermost layer of build gradle. The general work is to configure other sub projects. For example, add some attributes to the sub Project.
  • There is a file named settings under the root directory of the Project Gradle. This file is very important. The name must be settings Gradle. It is used to tell Gradle how many sub projects this multiprojects contains (which can be understood as modules in Android studio).

Reference link

Link 1

Tags: Java

Posted by Kwakhed on Sun, 17 Apr 2022 17:23:26 +0930