欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

NDK二

程序员文章站 2022-06-06 17:38:15
...

在升级Android Studio 到3.0后,因为项目的需求需要进行NDK开发,因为以前做过NDK开发,感觉so easy.

呵呵,在按照以前总结的经验,然后一栋操作猛如虎,然后......,各种报错。心里一万头*飞奔。


但是大体的思路还是和以前一样。参照NDK一开发博客。

在Android studio3.0后ndk开发必须要用cmake.

在这里需要注意的是cmake配置必须在ndk12r+下支持。

首先建立CMakeLists.txt文件在app下,必须是txt文件。不然会出现:

Error:Gradle project cmake.path specifies CMakelists.txt but it must be CMakeLists.txt   的错误。

CMakeLists.txt文件

cmake_minimum_required(VERSION 3.4.1)

include_directories(
    ${CMAKE_SOURCE_DIR}/src/main/cpp/include #h文件目录
)
add_library( # Sets the name of the library.
             jni-lib                        #c/cpp代码将要编译成为so库的名称,java代码加载库文件要用这个名称
             SHARED
             #src/main/cpp/hello-cjni.c      #c代码文件路径
             src/main/jni/test.cpp  #cpp代码文件路径 这里可以随意添加c、c++文件
              )
target_link_libraries( # Specifies the target library.
                       jni-lib
                       )

然后配置CmakeLists.txt,

 externalNativeBuild {
        cmake {
            path "CMakeLists.txt"//默认路径是在app/
        }
    }

然后配置cpu类型

externalNativeBuild {
    cmake {
        // Sets a flag to enable format macro constants for the C++ compiler.

        cppFlags "-std=c++11 -D__CORRECT_ISO_CPP_WCHAR_H_PROTO"
    }
    ndk {
        abiFilters "armeabi", "armeabi-v7a","x86"
    }
}

在grade下的整体结构如下

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.wzxl.nativedemo"
        minSdkVersion 19
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                // Sets a flag to enable format macro constants for the C++ compiler.

                cppFlags "-std=c++11 -D__CORRECT_ISO_CPP_WCHAR_H_PROTO"
            }
            ndk {
                abiFilters "armeabi", "armeabi-v7a","x86"
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            externalNativeBuild {
                cmake {
                    // Sets a flag to enable format macro constants for the C++ compiler.

                    cppFlags "-std=c++11 -D__CORRECT_ISO_CPP_WCHAR_H_PROTO"
                }
                ndk {
                    abiFilters "armeabi", "armeabi-v7a","x86"
                }
            }
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

然后就是上代码

public class TestNative {
    static {
        System.loadLibrary("jni-lib");
    }
    public static native String getShow();
    public static native int getNum(int a,int b);

}

然后进入Terminal编译器 进入Java 目录下,输入命令:

cd app/src/main/java
javah com.wzxl.nativedemo.TestNative

在Java目录下生成.h文件

在main目录下创建jni文件夹 

NDK二

把.h文件放到jni目录下

创建test.cpp文件导入.h 

#include"com_wzxl_nativedemo_TestNative.h"
复制.h文件里面的方法 书写返回值
JNIEXPORT jstring JNICALL Java_com_wzxl_nativedemo_TestNative_getShow
  (JNIEnv *env, jobject obj){
    return env->NewStringUTF("hello");
}
JNIEXPORT jint JNICALL Java_com_wzxl_nativedemo_TestNative_getNum
        (JNIEnv *env, jclass, jint a, jint b){
    return a+b;
}

然后rebuild 在build/intermediates/cmake下生成so动态库

然后调用代码:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView textView = findViewById(R.id.text);
        TestNative nat = new TestNative();
        Log.d("MainActivity",nat.getShow());
        Log.d("MainActivity","a+b的和等于"+nat.getNum(333,333));
        textView.setText(nat.getShow()+"\n"+"a+b的和等于"+nat.getNum(333,333));
    }
}

运行程序吧!!!!!

可能出现

java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String com.wzxl.nativedemo.TestNative.getShow() (tried Java_com_wzxl_nativedemo_TestNative_getShow and Java_com_wzxl_nativedemo_TestNative_getShow__)

这是因为你的.h文件中参数的类型和.cpp文件中的不同。

修改为相同就可以了

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

#ifndef _Included_com_wzxl_nativedemo_TestNative
#define _Included_com_wzxl_nativedemo_TestNative
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_wzxl_nativedemo_TestNative
 * Method:    getShow
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_wzxl_nativedemo_TestNative_getShow
  (JNIEnv *, jobject);

/*
 * Class:     com_wzxl_nativedemo_TestNative
 * Method:    getNum
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_wzxl_nativedemo_TestNative_getNum
  (JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

相关标签: NDK