Android 积累一些JNI与NDK的知识

安卓NDK开发实战:从JNI原理到性能优化与避坑指南 在移动开发领域,性能优化与底层硬件交互是高级开发的核心诉求。通过理解JNI(Java Native Interface)这一跨语言通信的桥梁,开发者能够突破Java虚拟机的限制,直接调用C/C++代码,实现性能敏感型计算和复用庞大的成熟生态库。其技术价值在于为应用提供了与系统底层、硬件及现有C/C++生态对话的能力,从而在图像处理、音视频编解码等场景中发挥关键作用。例如,在`ndk编译opencv3`这类任务中,正是通过NDK将计算机视觉库集成到安卓应用,解决了密集计算和算法复用的需求。同时,在`安卓缓存r 阅读详情

最近项目中要用到一些同屏操作,起初的方案是不断记录坐标,上传坐标,来达到画笔的同屏。但实际演示的时候效果并不好,于是我在想可不可以像视频录制一样直接调用底层,体验永远是程序质量的第一标准,不能因为自己的能力限制所妥协。但问题接踵而至,因为jvm的跨平台的特性,注定导致java跟底层几乎没什么联系。但是java能调用c方法,通过JNI的方式。在android程序中要想调用c方法,就要用到NDK,平常JNI和NDK说的很溜,其实我也不知道JNI与NDK的区别:


1.JNI与NDK的定义:


JNI:

Java Native Interface(Java 本地接口)
方便Java调用C,C++等本地代码所封装的一层接口

NDK:

Android 提供的一个工具集合(native develop kits),这套工具集允许你为android使用c或c++代码,并提供众多的平台库让你管理原生的activity和物理设备组件
通过NDK可以在android中更加方便的通过JNI来访问本地代码
交叉编译的工具链:在一个平台下,编译出来在另一个平台下可以执行的代码
.c 与 .java
1.编译:把源代码编译成一个低级语言,
2.链接:根据具体平台的特性,链接成一个二进制可执行的程序




工作环境()

应该是一个android程序员想要调用c方法,他要写成native方法,然后把nativie方法弄成头文件,
c程序员根据头文件里的方法,对其中的方法做实现,然后给android程序员再弄成so文件,弄成文件就简单了,开发过百度地图的都知道,建立jniLibs,将so文件放入,调用方法,实现功能。

运行环境:

as2.3.1

window64

ndk:android-ndk-r13b


NDK比较古老的使用方式:使用ndk-build命令


之前eclipse上使用ndk,或者ndk更早版本的时候,在官方的ndk目录里有ndk-build的文件,可惜只能在linux环境下运行,估计还要下cygwin模拟linux环境还要配置环境变量,而现在比较高的版本的ndk文件目录下有ndk-build.cmd文件,方便里我们可以直接在Android studo的Terminal控制台下直接编译成so库。


前言:

1.运行环境很重要,本人实验了一下午,发现低版本的ndk害死人,老是出Error:Execution failed for task ':app:compileDebugNdk'.这个错误,纠结代码半天,其实压根跟代码没啥关系

2.32位的系统androidstudio用不了cmake

3.android_studio看不了.mk文件

操作流程:

1.配置NDK与环境变量


配置ndk的环境变量跟配置jdk的环境变量差不多,自行百度

2.建立项目声明native方法
package com.wyt.hcy.libjpegandroid;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    static {
        System.loadLibrary("Hello");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv= (TextView) findViewById(R.id.tv);
        tv.setText(helloFromC());
    }




    public native String helloFromC();
}





3.形成头文件

在studio terminal中输入指令,切换到项目的目录,并输入javah 包名. MainActivity



刷新就会看到产生的头文件





点开这个头文件:

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

#ifndef _Included_com_wyt_hcy_libjpegandroid_MainActivity
#define _Included_com_wyt_hcy_libjpegandroid_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_wyt_hcy_libjpegandroid_MainActivity
 * Method:    helloFromC
 * Signature: ()Ljava/lang/String;
 */

/**
 * 函数名的格式Java_包名_类名_方法
 * JNIEnv:表示一个指向JNi环境的指针
 * jobject:表示java中的this
 * JNICALL,JNIEXPORT:表示JNi定义的宏
 */
JNIEXPORT jstring JNICALL Java_com_wyt_hcy_libjpegandroid_MainActivity_helloFromC
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

4.根据头文件实现方法

建立jni文件夹,选择main目录右键,new/folder/jnifolder

将头文件剪切到jni目录下

这里以c语言为例,在jni目录下建立Hello.c文件,要引入头文件
#include<stdio.h>
#include<jni.h>
#include "com_wyt_hcy_libjpegandroid_MainActivity.h"


JNIEXPORT jstring JNICALL Java_com_wyt_hcy_libjpegandroid_MainActivity_helloFromC(JNIEnv *env, jobject obj)
{

    return (*(*env)).NewStringUTF(env, "HelloWorldFromC");
}



5.编成so库

A。在jni目录下建立Android.mk文件(此文件名称固定:交叉编译器在编译c或者c++语言所依赖的配置文件符合linux下makefile的语法ziji),文件名字固定(不知道为什么),as是能建立.mk文件的,但打不开。



这里我用subnlite text打开它,在android.mk里输入

LOCAL_PATH := ${call my-dir}
include ${CLEAR_VARS}
LOCAL_MODULE :=Hello
LOCAL_SRC_FILES :=Hello.c
include ${BUILD_SHARED_LIBRARY}

LOCAL_PATH := ${call my-dir}  获取当前Android.mk文件的路径
include ${CLEAR_VARS}       变量的初始化但不会初始化LOCAL_PATH
LOCAL_MODULE :=Hello        libHello.so 表示模块名称,即:MainActivity静态代码块填写的
LOCAL_SRC_FILES :          表示参与编译的源文件



B。在项目的gradle.properties里配置:

android.useDeprecatedNdk=true


C。最后在module的build.grade里输入:(一定要在android里的
defaultConfig代码块里写:
)

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.wyt.hcy.libjpegandroid"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        ndk{
            moduleName "Hello"
            // abiFilters "armeabi", "armeabi-v7a", "x86"  //输出指定三种abi体系结构下的so库。目前可有可无。
        }

    }



在Terninal控制台里输入ndk-build成功就会返回




编译成功的话:在jni同级目录下会多了个libs目录,还能看到libHello.so



然后clean,运行就会看到textview调用了c代码


运行中出错:Error:Execution failed for task ':app:compileDebugNdk'. 

个人觉得不应该向其他人说的添加一个空的c文件就能解决的:

1.看看您
在项目的gradle.properties里配置:




2.看看项目的gradle里有没有设置ndk,或者当前项目的ndk版本是否跟你环境变量的版本一致



ndk-build clean 该命令可以删除编译的缓存



下面我们进行更深层次的探索


1.什么是cmake

一款外部构建工具,可与 Gradle 搭配使用来构建原生库。如果您只计划使用 ndk-build,则不需要此组件。

2.什么是LLDB

一种调试程序,Android Studio 使用它来调试原生代码。  


//最近我一直想使用libjpeg-turbo这个开源库,但我一直没找到如何将这个开源库编译成android的版本的方法,一开始我看教程上说,只要把开源库里的c文件得名字都放进Android.mk文件里just like:

 

我展示too young,以为直接编译能成功结果问题太多

jinclude.h:23:10: fatal error: 'jconfig.h' file not found
jpeglib.h:69:9: error: unknown type name 'JSAMPLE'

结果我就傻眼了,百度这些问题,压根没找到有用的,由于自己c语言早已忘得一干二净

于是我今天又找了个项目:项目下载链接

只要将文件复制到项目的jni目录下:打开as 控制台输入:

ndk-build APP_ABI=armeabi-v7a,armeabi
虽然有些警告,但直接编译成功了















AndroidStudio环境下的jni调用(NDK) AndroidStudio环境下的jni调用(NDK),这个教程可以让完全不会AndroidStudio的人学会jni调用。完全步骤话,非常简单。 立即下载

相关推荐

Android Studio NDK JNI配置Demo代码 2016

ndk demo开发过程在http://blog.csdn.net/gzjck/article/details/51724970

Android S#include <jni.h> file not found 解决办法

使用Android.mk 编译的模块在升级至S 或后续版本时提示 #include <jni.h> file not found 主要原因为 S 上默认去掉了 JINI_H_INCLUDE 定义,若要彻底修改,需要更改build路径下go文件,较为繁琐,另一种方法可以 LOCAL_HEADER_LIBRARIES := jni_headers

someWAP的博客 1377

NFS共享速度慢?麒麟系统性能调优5个关键参数实测对比

本文针对银河麒麟服务器系统上NFS共享速度慢的问题,通过实测对比分析了五个关键调优参数。重点探讨了rsize/wsize传输块大小、TCP/UDP协议选择、sync/async模式权衡等,并结合麒麟系统特性提供了具体的优化建议与配置示例,旨在帮助用户有效提升国产化环境下的文件共享性能。

weixin_29254029的博客 333

android 13 编译JNI报Android #include <jni.h> file not found 解决方法

JNI编译

u011557327的博客 882

【Proteus】NE555纯硬件实现LED呼吸灯效果,附源文件,效果展示

本设计通过NE555与三极管的巧妙配合,仅用基础元件实现了呼吸灯效果。核心在于利用RC积分电路将PWM信号转换为控制电压,并通过负反馈动态调节占空比。Proteus仿真验证了方案的可行性,读者可进一步优化参数或扩展功能,探索更多硬件设计可能性。

2201_75797484的博客 2979

ADS AEL脚本进阶:参数化电感与变压器的自动化设计

本文深入探讨了如何利用ADS AEL脚本实现电感与变压器的参数化与自动化设计。通过构建可复用的函数库、封装高级设计流程、集成DRC检查与性能预估,将繁琐的手动绘制升级为高效的智能设计引擎,并最终通过创建GUI工具降低使用门槛,大幅提升射频/微波电路设计效率。

weixin_29309785的博客 203

【NDK】【015】jni.h file not found

问题1:include文件找不到 问题2:include正常,但无法查看源码

天天向上 Up Up Up (*^▽^*) 2858

SAP-PM设备模块-PM主数据之维护策略

预防性维护的一种计划方式,需要先建立维护策略什么情况下需要创建维护策略?

TRUIXIANG的博客 2569

‘jni.h‘ file not found Android ndk 开发遇到的坑

项目场景: Android jni层开发中遇到的问题,ndk 和cmake的工具下载了最新的 问题描述: 在Android ndk开发中遇到个很奇怪的问题,新加一个 .h文件,老是找不到jni.h 头文件,报’jni.h’ file not found的错误,但是之前文件也不少用到了这个jni.h文件,没有发现错误,并且编辑器里有这个错误,照样可以正常运行代码。而我试着去新加一个 .cpp文件呢,只要同步几次确可以正常引入jni.h文件。百度谷歌搜索了一圈没找到办法。最后没辙忽略这个错误,反正能正常运行

HuangTieBing的博客 3702

RK3588 部署 YOLO26 目标检测:PT → ONNX → RKNN 全流程

YOLO26n 在 RK3588 上 INT8 量化后 NPU 推理约 15ms,系统 FPS 约 55,可以覆盖边缘端实时检测需求。模型从 PT 到 RKNN 的转换要用opset=11避免算子兼容问题。先用 YOLO26n + 640 输入跑通全链路,确认推理结果正确后再做性能调优。

m0_64661770的博客 303

078、镜头阴影校正:LSC算法原理与标定优化

文章摘要 镜头阴影校正(LSC)是手机影像系统中的关键技术,用于解决镜头渐晕效应导致的画面边缘暗角问题。本文详细分析了LSC算法的核心原理,包括非均匀网格划分、双线性插值等关键技术点,并揭示了标定流程中的常见陷阱(光源均匀性、灰卡反射特性、温度漂移)。文章还深入探讨了增益计算的工程实现细节,以及实际调优中的关键考量因素(色差校正、动态场景适应等)。作者结合15年经验,给出了包括验证方法、网格参数设计、产线标定等实用性建议,强调LSC算法应与光学设计协同优化,才能达到最佳效果。

sundong_81的博客 41

编译遇到:fatal error: ‘jni.h‘ file not found 报错

一招解决找不到jni.h编译报错

Eunice_L_7的博客 2572

Leads、SDR、MQL、SQL、L2C术语概念,线索创建与清洗、线索分级模型、线索流转策略、线索的统计与分析

CRM中的“Leads”是什么?笔者在文中不仅较为全面地介绍了相关术语概念,还分析了线索的创建与清洗、线索的分级模型、线索流转策略以及线索的统计与分析。

盼盼学士 5954

安卓开发实战讲解!阿里、腾讯大厂Android面试必问知识点系统梳理,含BATJM大厂

开头 Android开发中,热修复技术被越来越多的开发者使用,市面上也出现很多成熟的开源框架。但对大部分开发者来说,热修复依然是一个既熟悉又陌生的词。仅仅知道热修复的作用,会使用框架,那样意义并不大。我们还要知道热修复的原理,这样不管框架如何变化,只要基本原理不变,我们都可以快速掌握它,或者自己动手写一个适合项目的热修复框架。 NDK模块 一、C#与C++ 1.C#与C++数据类型归纳总结 2.C#与C++内存结构与管理 3.预处理指令、Typede 4.C与C++结构体、共同体 5.指针,智能指针、方法指

CHAMPION8888的博客 203

linux内核学习(一)---内核社区介绍及补丁提交

本系列开始会对linux内核进行系统性的学习,以源码与内核社区为基础,了解前沿的内核机制,同时也深度了解linux内核中的一些经典机制 本章会先对linux内核社区进行简单的介绍,包括源码下载、内核社区的修改提交

文艺小少年的博客 536

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

【原理+实战+视频+源码】抖音,快手大热背后—

通过单独的列举和使用这些API,对Android音视频处理有一个基本的轮廓,虽然知识点相对来说是比较散的,但是点成线,线称面,基本的基础掌握了,通过学习Android音视频核心的API将音视频的流程串联起来,这样对于音视频的了解和控制就不仅仅局限于最外层的API了,而是能够通过相对底层的方式来加深对Android 音视频开发的认知。学习 Android 平台 OpenGL ES API,了解 OpenGL 开发的基本流程,使用 OpenGL 绘制基本图形,并了解相关的API的简单使用。

2401_89308178的博客 965

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

离了JNI,NDK还能活吗? 深入探讨Android开发的双刃剑

在Android开发的世界里,Java和Kotlin是构建应用的主要语言。然而,对于需要高性能计算或者访问设备底层功能的场景,Java和Kotlin就显得力不从心。这时,JNI(Java Native Interface)和NDK(Native Development Kit)就显得尤为重要。本文将深入探讨JNI和NDK的概念、用途以及如何在Android开发中有效利用它们。

Unity打怪升级 952

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

NDK探究之旅《一》——对jni和NDK的认识

最近在学习NDK开发,这是NDK篇的第一节。对jni和ndk的基本认识。 JNI的基本概念? jni是一个协议。这个协议用来沟通Java代码和外部的本地代码(c/c++),通过这个协议 ,Java代码可以外部的c/c代码 ,外部的c/c代码也可以 调用本地的Java代码。 欢迎关注我的博文:http://blog.csdn.net/androidstarjack。 欢迎关注公众号: 终端研发部。一块学习

这个时代,作为程序员可能要学习小程序 5788

攻克Android面试:NDK与JNI核心问题全解析

你是否在Android面试中遇到NDK(Native Development Kit,原生开发工具包)和JNI(Java Native Interface,Java原生接口)相关问题时手足无措?本文将系统梳理这两个技术点的高频面试题,帮助你快速掌握核心概念与实战经验,轻松应对面试挑战。读完本文,你将能够清晰解释NDK/JNI的作用、使用场景、数据类型转换及常见问题解决方案。 ## NDK与JNI...

gitblog_01096的博客 504

JNI与NDK-联系和区别完美解释

1. JNI(java native interface) 作为一名android app 开发人员, 必须了解JNI。 JNI 是jave应用程序和native C/C++(C/C++被称为native language)代码的桥梁。 用途一:目前很多公司现有的代码都是C/C++的,这些代码是多年的积累,运行效率高 安全性好。在开发android app的时候,直接写JNI借口,供java应

zhangze 2026

安卓中的jni调用

背景 1、JNI: Java Native Interface。是一套编程接口,用来实现Java代码与本地的C/C++代码进行交互 2、用途: 可以通过JNI调用系统提供的api,因为操作系统或者抵触硬件驱动几乎都是c/c++写的。Java和C/C++不同 ,它不会直接编译成平台机器码,而是编译成虚拟机可以运行的Java字节码的.class文件,通过JIT技术即时编译成本地机器码,...

调上调下的女生 1401

Android杂项积累

平时工作内容基于安卓系统,确并不直接参与安卓部分开发,而只是为安卓层提供natvie方法的调用界面、实现以及再往下的BSP相关的驱动开发。但是总感觉理解安卓系统的一些重要特性也是有必要的。本文仅记录自己对安卓框架原理上的理解,无引导性、无实用性。 1、framework 使用java语言做终端开发的人大致分为两类:应用开发与framework开发。应用开发总的来说是使用安卓系统提供的原材料与框架编写特定需求的app,假如某些功能framework并未提供,例如你的产品需要使用一款奇葩的传感器,原生frame

卢平光的博客 1258

安卓之JNI 和 NDK编程(一)内部samples的调用

目录 一、前言 二、实战讲解 1>、NDK环境安装 1、不用安装Cygwin 2、Eclipse、ADT插件、NDK插件 3、注意点: 2>、项目案例讲解1-内部samples调用 3>、项目案例讲解2-so库的生成 一、前言 由于各种原因创业维艰,虽然市场行情不好但是不要灰心,坚持积累总结加油总会有自己的康庄大道的。好了废话少说,其实在2013年做视频开发的......

鲁迷那的专栏—坚持实践后再写出来! 590

Android Studio下 NDK配置与Jni开发流程

学习学习在学习,闲来无事找个东西学,一直觉得jni可以Java调用C很神奇,于是来探探玄奇,看了网上的关于AS开发环境下 jni的开发文章,对开发的流程还是有点疑问,于是自己动手琢磨了一下,并编写了简单的demo,理清楚了大致流程,本文着重讲述AS下的jni流程,不涉及代码的编写,记录下自己的积累过程,不正确的地方望指出!!! 概念性的就不讲了,来说说流程,说到底也就是那几步

qq_35353934的博客 464

JNI/NDK开发指南(开山篇)

转载请注明出处:         相信很多做过Java或Android开发的朋友经常会接触到JNI方面的技术,由其做过Android的朋友,为了应用的安全性,会将一些复杂的逻辑和算法通过本地代码(C或C++)来实现,然后打包成so动态库文件,并提供Java接口供应用层调用,这么做的目的主要就是为了提供应用的安全性,防止被反编译后被不法分子分析应用的逻辑。当然打包成so也不能说完全安全了,只是

技术改变生活 2万+

android NDK 教程一(初识JNI--hello world)

前言                android的知识太过庞杂了,自己如果学过了,但过一段时间不用了又会忘记。写android NDK系列的博客呢,其一是为了锻炼自己的写作水平,其二是为自己所学过所掌握的一些知识做一下梳理、记录,方便以后自己查阅。废话不多说,先写个hello world开始吧。       前期准备          开发工具:EclipseBundle ADT + an

淡泊明志,宁静致远 2550
上一篇: Android 模拟一个电子画板同屏的效果
下一篇: Android 积累一些常见的开发异常与问题
泡温泉的咸鱼
博客等级 码龄11年 39粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值