NDK开发流程

1 篇文章 0 订阅
1 篇文章 0 订阅

NDK开发学习笔记。

1、在Java代码里写native方法。可以在Activity中写native方法,也可以重新创建一个Java类写。我这里是重新创建一个Java类写的。

public class GetString {
    //native方法
    public native String getString();
}

2、在main目录下创建一个jni目录。用于存放头文件(.h)和源文件(.c)。

右击jni目录 -> New -> C/C++ Source File创建头文件和源文件

在弹出的弹窗中填写头文件和源文件的名称,勾选Create an associated header 可以同时生成头文件和源文件,如果不勾选,就只创建源文件。创建完,就可以在这两个文件中写C代码了。个人不是很喜欢这种方式创建头文件和源文件。

 

下面是第二种创建方式。

创建好jni目录后,打开Terminal,输入cd app/src/main/java 命令回车,

再输入 javah com.example.ndkdemo.GetString 回车。其中com.example.ndkdemo.GetString为你写native方法的类的全路径。

 cd app/src/main/java 

 javah com.example.ndkdemo.GetString

 稍等片刻,会在app/src/main/java路径下生成一个头文件

 把这个文件移动到jni目录下,打开该文件。

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_ndkdemo_GetString */

#ifndef _Included_com_example_ndkdemo_GetString
#define _Included_com_example_ndkdemo_GetString
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_ndkdemo_GetString
 * Method:    getString
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_ndkdemo_GetString_getString
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

JNIEXPORT jstring JNICALL Java_com_example_ndkdemo_GetString_getString
  (JNIEnv *, jobject);就是native方法在jni层生成的对应的方法。注意Java_com_example_ndkdemo_GetString_getString这个方法名不要修改。这个方法的命名格式为:Java_类的全路径名_方法名,中间用_隔开。使用第一种方式创建头文件和源文件,需要自己写方法名,很容易出错。

然后,右击jni目录 -> New -> C/C++ Source File创建源文件,只要不勾选Create an associated header就可以了。

3、将头文件中的方法 JNIEXPORT jstring JNICALL Java_com_example_ndkdemo_GetString_getString
  (JNIEnv *, jobject);复制到源文件中,去掉JNIEXPORT和JNICALL就可以去实现这个方法了。注意,这里需要将头文件引进来 #include "GetString.h"。

#include "GetString.h"

jstring Java_com_example_ndkdemo_GetString_getString
        (JNIEnv *env, jobject jobj) {
    return (*env)->NewStringUTF(env, "asdfghjkl");
}

 4、在app目录下创建CMakeLists.txt

CMakeList.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.
        GetString

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        src/main/jni/GetString.c
        src/main/jni/GetString.h
        )

# 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.

#这个函数的意思是给系统的log库起个别名,命名为log-lib
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.

#这个函数的意思是刚刚之前的命名的库一起link进去
target_link_libraries( # Specifies the target library.
        #        Hello
        #        JavaCallC
        GetString

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

  5、在build.gradle(app)的android->defaultConfig节点下添加ndk配置信息

ndk {
            abiFilters "armeabi-v7a" //cpu类型,会生成对应cpu的so文件
        }

      在android节点下配置CMakeLists信息

externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }

ndkVersion '21.4.7075529'

6、加载动态链接库

public class GetString {

    //加载动态链接库
    static {
        System.loadLibrary("GetString");
    }

    //native 方法
    public native String getString();
}

7、使用

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

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

        GetString getString = new GetString();
        findViewById(R.id.btnGetString).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String string = getString.getString();
                Log.d(TAG, "string -> " + string);
            }
        });
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值