240.Android Studio3.5 写 NDK 程序(1)

1.先给Android Studio配置NDK,可以直接在Tools---SDK Manager中,

240.Android Studio3.5 写 NDK 程序(1)_第1张图片

然后可以在File---Project Structure中配置好ndk的路径

240.Android Studio3.5 写 NDK 程序(1)_第2张图片

2.再针对这个ndk路径配置好环境变量,在系统变量下面添加一个变量名“NDK_ROOT”,值为NDK的路径。

240.Android Studio3.5 写 NDK 程序(1)_第3张图片

240.Android Studio3.5 写 NDK 程序(1)_第4张图片

最后在path中新建%NDK_ROOT%

240.Android Studio3.5 写 NDK 程序(1)_第5张图片

配置好了以后在cmd窗口输入ndk-build.cmd以后有下面的打印

240.Android Studio3.5 写 NDK 程序(1)_第6张图片

3.环境配置好了以后就可以写程序了

先创建一个JniDataUtil.java类,这个类是填充java需要调用c语言的方法的类

package com.ldw.jnitest;

/**
 * author: ldw
 * created on: 2019/10/13 2:13
 * description:
 */
public class JniDataUtil {

    //创建一个 native 方法
    public native static String get();
}

4.然后创建c语言,创建so

 打开 Android Studio 的 Terminal 到 移动到 app/src/main/java 目录下执行命令:javah -jni com.ldw.jnitest.JniDataUtil,

执行以后在java路径下生成com_ldw_jnitest_JniDataUtil.h

在app/src/main目录下创建一个jni的目录,然后将com_ldw_jnitest_JniDataUtil.h移动到jni的目录下,同时在 jni 目录下创建一个 c/c++ resource 文件 test.cpp,

#include
//导入我们创建的头文件
#include "com_ldw_jnitest_JniDataUtil.h"

#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_ldw_jnitest_JniDataUtil
 * Method:    get
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_ldw_jnitest_JniDataUtil_get
  (JNIEnv * env, jclass obj)
  {
    return env->NewStringUTF("This is my NDK Application");
  }

#ifdef __cplusplus
}
#endif

下面的这个方法使我们从头文件中复制过来的,头文件是自动生成的com_ldw_jnitest_JniDataUtil.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class com_ldw_jnitest_JniDataUtil */

#ifndef _Included_com_ldw_jnitest_JniDataUtil


#define _Included_com_ldw_jnitest_JniDataUtil
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_ldw_jnitest_JniDataUtil
 * Method:    get
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_ldw_jnitest_JniDataUtil_get
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

240.Android Studio3.5 写 NDK 程序(1)_第7张图片

 然后我们在 jni 目录下创建两个 .mk 文件:

    一个 Android.mk:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := JNITest
LOCAL_SRC_FILES := test.cpp
include $(BUILD_SHARED_LIBRARY)

 一个是 Application.mk:

APP_ABI := all

Android.mk参考

LOCAL_PATH:=$(call my-dir)

include $(CLEAR_VARS)

#libtestjni.so  //生成so的名字
LOCAL_MODULE := testjni   //生成模块的规则,生成的so的名字testjni
LOCAL_SRC_FILES := test.cpp   //生成模块的规则,so依赖的cpp文件可以有多个
LOCAL_LDLIBS := -llog    //生成模块的规则,当前so依赖的so

include $(BUILD_SHARED_LIBRARY)   //生成尾缀是so的文件

然后我们需要生成 so 库:

打开 Terminal,到 app/src/main/jni 目录下,使用 ndk-build 命令生成 so 库:

240.Android Studio3.5 写 NDK 程序(1)_第8张图片

                                 240.Android Studio3.5 写 NDK 程序(1)_第9张图片

接着打开 app/src/main/libs 就可以看见我们生成的 so 库了。

                                240.Android Studio3.5 写 NDK 程序(1)_第10张图片

5.为了防止 so 库兼容错误,在 gradle.properties 最后一行添加:

android.useDeprecatedNdk=true

240.Android Studio3.5 写 NDK 程序(1)_第11张图片

为了让项目能够找到我们的 so 库,在app下面的 build.gradle 文件夹的 android 下添加:

sourceSets {
     main() {
         jniLibs.srcDirs = ['src/main/libs']
         jni.srcDirs = [] //屏蔽掉默认的jni编译生成过程
     }
}

240.Android Studio3.5 写 NDK 程序(1)_第12张图片

6.然后我们在 JniDataUtil.java 中动态导入 so 库,不需要写 libJNITest,只用写 JNITest:

package com.ldw.jnitest;

/**
 * author: ldw
 * created on: 2019/10/13 2:13
 * description:
 */
public class JniDataUtil {

    // 动态导入 so 库
    static {
        System.loadLibrary("JNITest");
    }

    //创建一个 native 方法
    public native static String get();
}

然后我们在 MainActivity 中打印 JNITest 的 get() 方法获取到的 String 值,Toast中会弹出:This is my NDK Application

package com.ldw.jnitest;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private Button btn;

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

        initUi();
    }

    public void initUi(){
        btn = (Button) findViewById(R.id.button);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, JniDataUtil.get(), Toast.LENGTH_SHORT).show();
            }
        });
    }
}

240.Android Studio3.5 写 NDK 程序(1)_第13张图片

可以参考文档:https://blog.csdn.net/young_time/article/details/80346631

你可能感兴趣的:(android整理)