传统方式的具体流程
1.新建java NDKTools类
package gebilaolitou.ndkdemo;
public class NDKTools {
public static native String getStringFromNDK();
}
在java当前目录下执行下面的命令javah -jni gebilaolitou.ndkdemo.NDKTools。如果没有问题,则会java当前目录生成gebilaolitou_ndkdemo_NDKTools.h文件
内容如下
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class gebilaolitou_ndkdemo_NDKTools */
#ifndef _Included_gebilaolitou_ndkdemo_NDKTools
#define _Included_gebilaolitou_ndkdemo_NDKTools
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: gebilaolitou_ndkdemo_NDKTools
* Method: getStringFromNDK
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_gebilaolitou_ndkdemo_NDKTools_getStringFromNDK
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
2.新建jni文件夹,把生成的gebilaolitou_ndkdemo_NDKTools.h文件放到这个目录下,并再新建2个文件,一个c文件ndkdemotest.c 和 Android.mk文件。
注意:此处的c文件也可以是cpp文件,看你是c代码还是c++代码。
ndkdemotest.c文件内容如下
#include "gebilaolitou_ndkdemo_NDKTools.h"
JNIEXPORT jstring JNICALL Java_gebilaolitou_ndkdemo_NDKTools_getStringFromNDK
(JNIEnv *env, jobject obj){
return (*env)->NewStringUTF(env,"Hellow World,这是隔壁老李头的NDK的第一行代码");
}
Android.mk文件如下
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ndkdemotest-jni
LOCAL_SRC_FILES := ndkdemotest.c
include $(BUILD_SHARED_LIBRARY)
3.检查local.properties文件中是否有NDK路径,如果有没有NDK路径,则添加NDK路径,比如我的如下:
ndk.dir=/Users/lijie/Library/Android/sdk/ndk-bundle
sdk.dir=/Users/lijie/Library/Android/sdk
其次修改app module目录下的build.gradle中的内容,如下:
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "chn.fz.thatjay.scrolleditview"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
externalNativeBuild {
ndkBuild {
path 'src/main/jni/Android.mk'
}
}
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.gyf.immersionbar:immersionbar:2.3.3'
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.orhanobut:logger:2.2.0'
api 'com.yanzhenjie.permission:support:2.0.1'
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'
}
执行代码效果:
static {
System.loadLibrary("ndkdemotest-jni");
}
private void test(){
Log.d("hahaha", NDKTools.getStringFromNDK());
}
控制台输入打印:
Hellow World,这是隔壁老李头的NDK的第一行代码
4.传统方式的so文件
那so去哪里了,我们平时使用第三方的sdk的so的时候,会要粘贴复制到项目里面,而我们上所述整个过程,并没有出现.so这个文件,那么这个.so去哪里了?
其实Android Studio自动帮我们把so放到apk里面,如果我们想找也能找到,如下图:
注意:我用mac mumu模拟器运行,目前就x86文件夹有生成so文件,其他文件夹没有so文件。
本人电脑屏幕太小,分成两张图截。
通过CMake工具demo演示流
1.CMake安装
2.新建项目,选择Native C++项目![在这里插入图片描述](https://img-blog.csdnimg.cn/20210307154655775.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d1c2VqaWVnZTY=,size_16,color_FFFFFF,t_70)
在Android Studio 完成新项目的创建后,请从IDE左侧打开Project 矿口并选择Android 视图。如下图所示,Android Studio 将添加cpp和External Build Files 组:
直接运行项目
我们来直接 run一下这个项目,看下结果
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_chn_fz_thatjay_myapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
执行代码效果:
package chn.fz.thatjay.myapplication;
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(stringFromJNI());
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
}
CMake工具demo的背后原理
我们看打了,我们什么都没做,就自动实现了C++的实现,它的背后原理是什么那?我们大家就思考一下?
CMake的入口
它既然可以跑起来,一定有一个入口,那这个入口在哪里那?
先和大家说下我是怎么想象的,首先我们在点击Android Studio中的run按钮的时候,它是执行Gradle来进行打包的,所以说关于CMake的是怎么植入进去的,一定在项目的build.gradle,有相应的入口。