NDK二
在升级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文件夹
把.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
上一篇: php-登录与业务分离的两个系统之间如何保证Token有效
下一篇: AC自动机