C call Java code graphic detailed explanation

Environment build

1. android studio2021.2.1

2. JDK version 1.8

1. Create an android project 

File ——> New ——> New Project ——> Empty Activity

After creation, as shown in the figure below

 Two, C calls java code process

2.1 Write java class code

Create a java JNI class, write trigger C code, and let C call java's cCallJava() method

    /**
     * 触发C代码让其调用cCallJava()方法
     */
    public native void callbackCCallJava();

    public void cCallJava(){
        System.out.println("C调用到了java的方法cCallJava");
    }

2.2 Generate the header file of the corresponding C code

(1) AS opens the Terminal window

Click Terminal on the bottom navigation bar

 (2) Use the command to open the directory where the JNI class is located

 In the Terminal window, enter cd app\src\main\java\com\zaq\ccalljava and press the Enter key on the keyboard

 (3) Generate the header file with the command

javac -encoding utf8 -h . JNI.java ( note: -encoding utf8 specifies the source file encoding format, there is a dot after -h, there is a space before and after the dot, the dot means the header file is generated in the current directory )

After execution, a jni header file com_zaq_ccalljave_JNI.h will be automatically generated, as shown in the following figure:

 2.3 Set the compilation method ndk-build related configuration

(1) Create a jni folder under main

 (2) Move the header file to the jni folder and delete JNI.class

(3) Create a C/C++ Source File under jni and name it Test.c.

(4) Create the file Android.mk under jni

Contents of Android.mk

#表示Android.mk所在目录
LOCAL_PATH := $(call my-dir)

#CLEAR_VARS变量指向特殊 GNU Makefile,用于清除部分LOCAL_变量
include $(CLEAR_VARS)

#模块名称
LOCAL_MODULE    := javacallc
#构建系统用于生成模块的源文件列表
LOCAL_SRC_FILES := Test.c

#BUILD_SHARED_LIBRARY 表示.so动态库
#BUILD_STATIC_LIBRARY 表示.a静态库
include $(BUILD_SHARED_LIBRARY)

 (5) Configuration in gradle.build to generate so library files

①The defaultConfig configuration in android

//定义ndkBuild默认配置属性
 externalNativeBuild {
     ndkBuild {
         cppFlags ""
     }
 }
 ndk {
     // 生成指定CPU平台对应的so库文件
     abiFilters "arm64-v8a"
 }

② Configuration at the same level as defaultConfig

//定义ndkBuild对应的Android.mk路径(重要)
externalNativeBuild {
    ndkBuild{
        path file("src/main/jni/Android.mk")
    }
}

 View the so generated file

Rebuild Project, that is, click File in the status bar --> Rebuild Project

The final name of the so file is lib+ccalljava (Android, the module name in the mk file).so, namely: libccalljava.so

The final path to generate the so library file is as follows:

 2.4 Realization of T-code

(1) Test.c code implements calling java method

#include "com_zaq_ccalljava_JNI.h"
#include <jni.h>
#include <stdlib.h>
#include <stdio.h>

/**
 * 调用java代码中JNI类里面的public void cCallJava()
 * @param env
 * @param jobj
 */
JNIEXPORT void JNICALL Java_com_zaq_ccalljava_JNI_callbackCCallJava
        (JNIEnv *env, jobject jobj){
    // 1.得到字节码
    // jclass      (*FindClass)(JNIEnv*, const char*);
    jclass jclazz=(*env)->FindClass(env,"com/zaq/ccalljava/JNI");

    // 2.得到方法
    // jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
    jmethodID jmethodIDs=(*env)->GetMethodID(env,jclazz,"cCallJava", "()V");

    // 3.实例化该类
    // jobject     (*AllocObject)(JNIEnv*, jclass);
    jobject obj=(*env)->AllocObject(env,jclazz);

    // 4.调用方法
    // void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
    (*env)->CallVoidMethod(env,obj,jmethodIDs);// 可成功调用JNI类中的public void cCallJava()
}

 (2) MainActivity mobilizes the method of JNI class

 (3) JNI class loading so file

(4) Run and install the apk, click the button and there will be log output, indicating that C successfully calls the java method 

 

Guess you like

Origin blog.csdn.net/zaq977684/article/details/130742626