Android studio CMakeLists JNI静态、动态注册

环境配置:
NDK、CMake
在这里插入图片描述

打开as后新建C++工程
在这里插入图片描述
进来后AS会帮我们在MainActivity中写一个小demo
我们只需要在其增删改就行了

MainActivity.java


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");
    }

    @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(dynamicFromJNI2(1.1f,2.2f)+"");  //show哪个函数就调哪个
    }

    /**
     * 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 addFromJNI(int x, int y);

    public native String dynamicFromJNI();  //动态注册
    public native float dynamicFromJNI2(float x,float y);  //动态注册 并参数
}

这里so层我是使用C语言编写的
C++的可以看这个博客:https://www.jianshu.com/p/20cfebfc1f20
因为是c语言所以我将AS生成的cpp文件改成了c文件
在这里插入图片描述

改为文件后我们也要修改CMakeLists.txt文件这个文件是之前版本Application.mak Android.mak的文件整合,所以我们只需要在哪里修改即可
CMakeLists.txt

# 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.c )   //这里修改成自己的c文件

# 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} )

native-lib.c

#include <jni.h>


jstring Java_com_example_jni_1demo_MainActivity_stringFromJNI(JNIEnv *env, jclass jcs){
    return (*env)-> NewStringUTF(env,"Hello form C");
}


jint Java_com_example_jni_1demo_MainActivity_addFromJNI(JNIEnv *env,jclass jcs, jint x, jint y){
    return x+y;
}

//动态注册的方法
jstring getDynamic(JNIEnv *env, jobject this){
    return (*env)-> NewStringUTF(env,"Hello Dynamic Native");
}

//动态注册的方法2
jfloat getDynamic2(JNIEnv *env, jobject this,jfloat jx,jfloat jy){
    return jx+jy;
}

//需要动态注册的方法组
JNINativeMethod gMethods[] ={
        {"dynamicFromJNI2", "(FF)F",(void*)getDynamic2},  //传参的函数声明
        {"dynamicFromJNI","()Ljava/lang/String;",(void*)getDynamic}
};

//调用RegisterNatives方法注册函数
int registerNativeMethods(JNIEnv *env) {    //JNIEnv : JavaVM 在线程中的代表, 每一个线程都有一个, JNI 中可能有非常多个 JNIEnv;
    jclass cls = (*env) -> FindClass(env,"com/example/jni_demo/MainActivity");
    if((*env) -> RegisterNatives(env,cls,gMethods, sizeof(gMethods) / sizeof(gMethods[0])))
        return -1;
    if((*env) -> RegisterNatives(env,cls,gMethods, sizeof(gMethods) / sizeof(gMethods[1])))  //这里返回方法组的第二个
        return -1;
    return 0;
}

//动态注册时都会执行到这个方法中
jint JNI_OnLoad(JavaVM *vm, void *unused) {     //JavaVM : JavaVM 是 Java虚拟机在 JNI 层的代表, JNI 全局仅仅有一个;
    JNIEnv* env;
    if ((*vm) -> GetEnv(vm,(void**)&env,JNI_VERSION_1_4) != JNI_OK || registerNativeMethods(env) != JNI_OK)
        return JNI_ERR;
    return JNI_VERSION_1_4;
}


关于方法的解释都写在代码里面了,这样好对应位置解释看起来容易懂。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值