android studio 调用C++代码

2023-05-16

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android studio 调用C++代码 的相关文章

  • 测试权限和 Android 应用清单文件

    我想知道是否有办法添加某些权限 或任何东西 到 android 清单文件 但这样它仅在测试运行期间使用 不在生产期间使用 我正在寻找一些程序化的东西 而不是在测试时剪切和粘贴 这是上下文 我正在读这篇文章 http developer an
  • Android 2.1:如何轮询现有蓝牙连接的 RSSI 值?

    我需要知道使用 Android 2 1 手机与远程设备建立蓝牙连接的信号强度 从SDK中 我可以看到我可以在发现远程设备时确定RSSI 但我不知道如何随着时间的推移更新该 RSSI 值 有人可以帮我吗 谢谢 从 SDK 中这是获取 RSSI
  • 在 Android 中设置 Signalr:崩溃/挂起问题

    我跟着本教程 https whathecode wordpress com 2014 03 20 getting started with the java signalr sdk 为我的 Android 应用程序设置一个 NET 后端来实
  • Android - NumberPicker 滚动/快速滑动更快

    如何使数字选择器滚动 快速滑动更快 目前从00分钟到59分钟需要付出很大的努力 我尝试过一些例子Android 中 Viewpager 控制器速度减慢 https stackoverflow com questions 8155257 sl
  • Android/iOS 上的相机远程快门如何工作?

    我最近在 Android iOS 上遇到了一个使用蓝牙的内置相机应用程序的远程快门 这是我找到的产品的示例链接 Link http www youtube com watch v cyVG76HDvh4 不是来打广告的 只是简单了解背后的技
  • ViewPager 具有不同的纵向和横向适配器

    在纵向模式下 我的ViewPager有 3 个片段 A B C 但在横向模式下 它只有 2 个片段 A 和 C 所以我创建了 2 个FragmentStatePagerAdapters 代表每种模式 问题是当屏幕方向改变时 ViewPage
  • RxJava 相当于 orElse 是什么

    在其他语言的流 函数域中有一个常见的操作 那就是 orElse 它就像一个 if 当当前链没有得到任何结果时 它会更改为备用链 在具有 Maybe 类型的语言中 它基本上会继续 Some 类型的链或更改为 None 类型的 orElse 理
  • 以编程方式创建进度绘制

    我有一个场景 我需要有大量的进度条可绘制对象 我无法为所有这些创建 xml 资源 因为我希望用户选择一种颜色 然后用于动态创建可绘制对象 下面是 xml 中的一个这样的可绘制对象 我如何以编程方式创建这个精确的可绘制对象
  • 创建 Android 智能应用横幅

    Android 设备有类似 iOS 6 智能应用横幅的解决方案吗 这是智能应用横幅的代码 从 Chrome 44 Beta 开始 您可以在 Android 版 Chrome 中推送您的应用程序 您网站上的本机应用程序安装横幅 请看下面的答案
  • 使用自定义布局时 AlertDialog 按钮不可见

    我想要在弹出窗口中使用自定义布局 所以我使用了警报对话框 由于弹出窗口中的子视图数量是动态决定的 所以我使用了 ScrollView 现在 扭曲来了 当没有剩余空间并且滚动开始运行时 正向和负向按钮将变得不可见 下面是代码 AlertDia
  • 将 SearchView 阈值设置为零

    我在用SearchView在android中 我将适配器设置为搜索视图 但建议弹出框在一个字符后显示 因为我将阈值设置为1 它不接受小于1的数字 如何将阈值设置为零 请喜欢 Google 因为您可能知道 Google Play 的应用程序没
  • 在视图上按下按键时不会调用 onKeyDown

    我有一个包含两个视图的活动 一个视图重写 onDraw 并正确处理 onTouchEvent 但是当我尝试检索第二个视图的 onKeyDown 时 它没有给我任何结果 相反 当我按下后退按钮或任何其他键盘按钮时 会调用 onKeyDown
  • 如何:获取 AVD 的端口号并向其自身发送消息

    我该如何执行以下操作 获取我的 AVD 的端口号 从我的代码而不是命令行 使用步骤 1 中获得的端口号从 AVD 向自身发送消息 这是可能的 模拟器可以给自己发送短信吗 https stackoverflow com questions 8
  • 如何使用带有 ListView 和自定义适配器的选择器来指示所选项目

    我有一个具有 ListView 的活动 并且我创建了一个自定义适配器 基于BaseAdapter 自定义适配器的 GetView 方法使用自定义布局 view context LayoutInflater Inflate Resource
  • 如何在真实设备上模拟来电? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 出于测试目的 我想在真实的 Andr
  • adb shell 的 BroadcastReceiver 权限

    考虑一个简单的工具 使用BroadcastReceiver实现一个简单的目标 因为这不应该被其他应用程序使用 所以它定义了一个保护级别为signature or signatureOrSystem
  • Android 上页面留在后台时会触发“beforeunload”事件

    我正在尝试制作一个在导航时弹出的简单加载微调器 它在导航离开时使用 beforeunload 事件显示 并在完成后使用 load 事件再次隐藏自身 问题是 当我将页面留在手机后台时 例如几个小时后 beforeunload 事件触发并显示微
  • Flury 分析可以提供整数信息的平均值吗?

    我需要将 Flurry 与 Android 集成 并想知道用户将在主屏幕上停留多长时间 以分钟为单位 使用 Flurry 可以得到这样的分析吗 当我检查 Flurry 时 它为我提供了特定屏幕上点击计数的统计数据 我想知道的是用户在主屏幕上
  • 安卓应用安全

    我想开发一个用户数据非常敏感的应用程序 我是开发新手 所以不确定以下内容 技术对于安全或高效来说是必要的 请留下您的评论 提前致谢 为了额外的安全性 我们可以避开市场 游戏商店 并将应用程序安装在个人设备上 它会让它更安全吗 我必须在设备上
  • ViewPager 中的 PagerTabStrip 位置

    我有以下代码

随机推荐

  • bat修改hosts文件

    attrib R C WINDOWS system32 drivers etc hosts 64 echo 64 echo 127 0 0 1 aaaa bbb com gt gt C WINDOWS system32 drivers et
  • 使用org.apache.tools.zip实现zip压缩和解压

    import java io import org apache tools zip import java util Enumeration 功能 zip压缩 解压 支持中文文件名 说明 本程序通过使用Apache Ant里提供的zip工
  • freeModbus代码解读及移植笔记

    freeModbus的代码库还是很好用的 xff0c 本人在wince和C8051F410下均移植成功 xff08 只用到RTU模式 xff09 但freeModbus提供的文档比较少 xff0c 只能对照着Modbus协议一点点试着读懂源
  • MySQL变量:local_infile

    local infile服务器变量指示能否使用load data local infile命令 该变量默认为ON 该变量为OFF时 xff0c 禁用客户端的load data local infile命令 Sql代码 mysql gt sh
  • strcpy函数实现

    C语言标准库函数strcpy的一种典型的工业级的最简实现 返回值 xff1a 返回目标串的地址 对于出现异常的情况ANSI C99标准并未定义 xff0c 故由实现者决定返回值 xff0c 通常为NULL 参数 xff1a strDesti
  • C++库介绍

    1 C 43 43 标准库 xff08 STL xff09 STL六大组件 容器 算法 迭代器 仿函数 适配器 配接器 空间配置器 1 容器 各种数据结构 xff0c 如vector list deque set map等 xff0c 用来
  • 【C++】extern “C“ 用法详解

    前言 前面简单了解了C 43 43 中的extern 34 C 34 之后 xff0c 可能很多小伙伴对这个陌生的词非常困惑 xff0c 不能理解他的使用场景 所以本章内容就来详细了解extern 34 C 34 的用法 xff0c 这里使
  • FreeRTOS学习第三篇——FreeRTOS任务创建(下)

    声明 xff1a 本文为博主的学习篇章 xff0c 欢迎大家指错 xff0c 共同学习 在解决一下上篇遗留下来的问题之前 xff0c 还得提前做些功课 xff0c 了解一些FreeRTOS的全局变量 PRIVILEGED DATA stat
  • printf用法之打印二进制,八进制,十进制,十六进制

    printf用法之打印2进制 xff0c 八进制 xff0c 十进制 xff0c 十六进制 printf是格式化输出函数 xff0c 它可以直接打印十进制 xff0c 八进制 xff0c 十六进制 xff0c 输出控制符分别为 d o x
  • 【飞控开发基础教程7】疯壳·开源编队无人机-SPI(气压计数据获取)

    COCOFLY教程 疯壳 无人机 系列 SPI xff08 气压计数据获取 xff09 图1 一 SPL06 简介 SPL06 是歌尔公司最新推出新款气压传感器 xff0c 最新推出新款气压传感器SPL06 001 xff0c 歌尔是全球领
  • 【遥控器开发基础教程5】疯壳·开源编队无人机-SPI(2.4G 双机通信)

    COCOFLY教程 疯壳无人机 系列 SPI 2 4G 双机通信 图1 一 NRF24L01 1 1 NRF24L01 简介 NRF24L01 是由NORDIC 生产的工作在 2 4GHz 2 5GHz 的ISM 频段的单片无线收发器芯片
  • tcp之IO模型

    5种io模型 tcp服务器分为了5种io复用模型 分别是 阻塞io模型 非阻塞io模型 io复用 信号驱动io 异步io 本文会讲前面3种io模型的tcp服务器实现 本文只做tcp服务器实现 客户端逻辑处理 接收数据等缓冲区不做深入说明 简
  • C语言带参数的宏定义

    C语言允许宏带有参数 在宏定义中的参数称为 形式参数 xff0c 在宏调用中的参数称为 实际参数 xff0c 这点和函数有些类似 对带参数的宏 xff0c 在展开过程中不仅要进行字符串替换 xff0c 还要用实参去替换形参 带参宏定义的一般
  • Ubuntu U盘安装时安装时卡在Syslinux的问题

    用软碟通制作的U盘启动 xff0c ubuntu是11 10版本 xff0c 安装时显示 xff1a SYSLINUX 3 86 2010 04 01 EBIOS Copyright C 1994 2010 H Peter Anvin et
  • new 对象加括号和不加括号的区别

    原文 xff1a http www java123 net v 951963 html 在new对象的时候有加上 xff0c 有不加 xff0c 不知道这个到底是什么区别 xff1f 比如 xff1a CBase base 61 new C
  • cocos2d-x 3.x游戏开发学习笔记(1)--mac下配置cocos2d-x 3.x开发环境

    原文 xff1a http blog csdn net likendsl article details 34617725 打开用户目录下 bash profile文件 xff0c 配置环境 python view plain copy p
  • cocos2dx[3.2](15)——颜色混合BlendFunc

    原文 xff1a 点此 1 概念 混合 是指两种颜色的叠加方式 在新图片将要渲染画到屏幕上的时候 xff0c 将用在新图片中的红 绿 蓝和透明度信息 xff0c 与屏幕上已经存在的图片颜色信息相融合 说的具体一点 xff0c 就是把某一像素
  • 整理一些面试可能会遇到的算法题目

    将两个有序的单链表合并为一个有序的单链表 xff0c 默认是按升序排列的 两路归并排序 xff08 升序排列 xff09 平均 最差 时间复杂度O NlogN typedef struct Node t struct Node t next
  • IIS写权限的利用

    源地址 xff1a http netsecurity 51cto com art 200812 101015 htm IIS写权限对网站系统的安全是致命的 xff0c 拥有写权限可以直接往网站目录写文件 xff0c 在拥有写权限的服务器上
  • android studio 调用C++代码

    Android studio调用C 43 43 代码 JNI原理 JNI Java Native Interface 叫做JAVA本地接口 JAVA是一种跨平台的语言 xff0c 这种特性依赖的是Java虚拟机 xff0c 虚拟机由C C