0
点赞
收藏
分享

微信扫一扫

android studio 调用C++代码

丹柯yx 2022-04-17 阅读 79
java

Android studio调用C++代码

JNI原理

JNI(Java Native Interface)叫做JAVA本地接口。

JAVA是一种跨平台的语言,这种特性依赖的是Java虚拟机,虚拟机由C/C++编写。适配各个系统,通过JNI为上层的JAVA应用提供各种服务,保证跨平台性。

JNI查找

Android系统在启动启动过程中,先启动Kernel创建init进程,紧接着由init进程fork第一个横穿Java和C/C++的进程,即Zygote进程。Zygote启动过程中会AndroidRuntime.cpp中的startVm创建虚拟机,VM创建完成后,紧接着调用startReg完成虚拟机中的JNI方法注册。

Java层怎么去找到相应的native代码的相应位置

package android.os;
public final class MessageQueue {
    private native void nativePollOnce(long ptr, int timeoutMillis);
}

步骤1: MessageQueue.java的全限定名为android.os.MessageQueue.java,完整的方法名为android.os.MessageQueue.nativePollOnce(),与之相对应的native层方法名是将点号替换为下划线,即android_os_MessageQueue_nativePollOnce()。

步骤2: 有了native方法,那么接下来需要知道该native方法所在那个文件。前面已经介绍过Android系统启动时就已经注册了大量的JNI方法,见AndroidRuntime.cpp的gRegJNI数组。这些注册方法命令方式:

register_[包名]_[类名]

那么MessageQueue.java所定义的jni注册方法名应该是register_android_os_MessageQueue,的确存在于gRegJNI数组,说明这次JNI注册过程是在开机过程完成。 该方法在AndroidRuntime.cpp申明为extern方法:

extern int register_android_os_MessageQueue(JNIEnv* env);

这些extern方法绝大多数位于/framework/base/core/jni/目录,大多数情况下native文件命名方式:

[包名]_[类名].cpp
[包名]_[类名].h

Tips: /android/os路径下的MessageQueue.java ==> android_os_MessageQueue.cpp

打开android_os_MessageQueue.cpp文件,搜索android_os_MessageQueue_nativePollOnce方法,这便找到了目标方法:

static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj, jlong ptr, jint timeoutMillis) {
    NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
    nativeMessageQueue->pollOnce(env, obj, timeoutMillis);
}

到这里完成了一次从Java层方法搜索到所对应的C++方法的过程。

Android studio调用c++

构建流程

首先创建一个Native C++的工程

就会发现IDE为我们自动生了一系列文件。这里讲一下重点的几个文件

app/src/java里面存放点是java源代码。app/src/cpp存放的是c++源代码

cpp目录下面有CMakeLists.txt文件,里面包含着动态库生成的规则设置。

add_library( # Sets the name of the library.
        jin_text

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        native-lib.cpp)

app下面的项目build、gradle如下

plugins {
    id 'com.android.application'
}

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.example.jin_text"
        minSdk 23
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags '-std=c++11'
            }
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    externalNativeBuild {
        cmake {
            path file('src/main/cpp/CMakeLists.txt')
            version '3.18.1'
        }
    }
    buildFeatures {
        viewBinding true
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

Plugiuns 是使用的插件,一般有两个

  • ‘com.android.application’,表示该模块为应用程序模块,可以直接运行,打包得到的是.apk文件
  • ‘com.android.library’,表示该模块为库模块,只能作为代码库依附于别的应用程序模块来运行,打包得到的是.aar文件

android是一个闭包。配置项目的各种属性

具体闭包功能可以自己百度。

Implementation 远程依赖声明。

之后只需要编写JNI接口(可以使用javah)生成,之后就可以调用C++代码。

Gradle

Gradle是一个架构项目的框架,真正起作用的还是plugin。Gradle中主要有两个对象Project和Task。其中Project为Task提供了上下文。Gradle脚本采用groovy书写。

Gradle的构建由一个或者多个project构成,每个project可以构建成你想要的样子,比如web应用、jar包等。

每个projext都是由多个Tasks组成的,每个task都代表着构建过程中的一个原子操作(编译、打包等)

Gradle的执行是分为两个阶段

  1. 配置阶段,读取所有build.gradle的内容来配置project和task等。
  2. 执行阶段
  • Gradle为每个build.gradle都会创建一个相应的Project领域对象,在编写Gradle脚本时,我们实际上是在操作诸如Project这样的Gradle领域对象。在多Project的项目中,我们会操作多个Project领域对象。Gradle提供了强大的多Project构建支持。
  • 要创建多Project的Gradle项目,我们首先需要在根(Root)Project中加入名为settings.gradle的配置文件,该文件应该包含各个子Project的名称。Gradle中的Project可以简单的映射为AndroidStudio中的Module。
  • 在最外层的build.gradle。一般干得活是:配置其他子Project的。比如为子Project添加一些属性。
  • 在项目根目录下有个一个名为settings.gradle。这个文件很重要,名字必须是settings.gradle。它里边用来告诉Gradle,这个multiprojects包含多少个子Project(可以理解为AndroidStudio中Module)。

参考链接

链接1

举报

相关推荐

0 条评论