欢迎来到皮皮网网站!

【github 换脸源码】【源码底层】【vecctor源码】jni源码编译

时间:2024-12-22 20:46:56 来源:cci加强指标源码

1.如何在Android下使用JNI
2.用jni写的安卓应用能被反编译吗
3.音视频探索(5):JPEG格式与Libjpeg库编译移植
4.Android开发中的源译NDK到底是什么?(详细解析+案例)

jni源码编译

如何在Android下使用JNI

       ã€€ã€€1.引言

       ã€€ã€€æˆ‘们知道,Android系统的底层库由c/c++编写,上层Android应用程序通过Java虚拟机调用底层接口,衔接底层c/c++库与Java应用程序间的接口正是JNI(JavaNative Interface)。本文描述了如何在ubuntu下配置AndroidJNI的开发环境,以及如何编写一个简单的c函数库和JNI接口,并通过编写Java程序调用这些接口,最终运行在模拟器上的过程。

       ã€€ã€€2.环境配置

       ã€€ã€€2.1.安装jdk1.6

       ã€€ã€€ï¼ˆ1)从jdk官方网站下载jdk-6u-linux-i.bin文件。

       ã€€ã€€ï¼ˆ2)执行jdk安装文件

       ã€€ã€€[html] view plaincopyprint?

       ã€€ã€€.$chmod a+x jdk-6u-linux-i.bin

       ã€€ã€€.$jdk-6u-linux-i.bin

       ã€€ã€€$chmod a+x jdk-6u-linux-i.bin

       ã€€ã€€$jdk-6u-linux-i.bin

       ã€€ã€€(3)配置jdk环境变量

       ã€€ã€€[html] view plaincopyprint?

       ã€€ã€€.$sudo vim /etc/profile

       ã€€ã€€.#JAVAEVIRENMENT

       ã€€ã€€.exportJAVA_HOME=/usr/lib/java/jdk1.6.0_

       ã€€ã€€.exportJRE_HOME=$JAVA_HOME/jre

       ã€€ã€€.exportCLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH

       ã€€ã€€.exportPATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

       ã€€ã€€$sudo vim /etc/profile

       ã€€ã€€#JAVAEVIRENMENT

       ã€€ã€€exportJAVA_HOME=/usr/lib/java/jdk1.6.0_

       ã€€ã€€exportJRE_HOME=$JAVA_HOME/jre

       ã€€ã€€exportCLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH

       ã€€ã€€exportPATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

       ã€€ã€€ä¿å­˜åŽé€€å‡ºç¼–辑,并重启系统。

       ã€€ã€€ï¼ˆ4)验证安装

       ã€€ã€€[html] view plaincopyprint?

       ã€€ã€€.$java -version

       ã€€ã€€.javaversion "1.6.0_"

       ã€€ã€€.Java(TM)SE Runtime Environment (build 1.6.0_-b)

       ã€€ã€€.JavaHotSpot(TM) Server VM (build .4-b, mixed mode)

       ã€€ã€€.$javah

       ã€€ã€€.用法:javah[选项]<ç±»>

       ã€€ã€€.其中[选项]包括:

       ã€€ã€€.-help输出此帮助消息并退出

       ã€€ã€€.-classpath<路径>用于装入类的路径

       ã€€ã€€.-bootclasspath<路径>用于装入引导类的路径

       ã€€ã€€.-d<目录>输出目录

       ã€€ã€€.-o<文件>输出文件(只能使用-d或-o中的一个)

       ã€€ã€€.-jni生成JNI样式的头文件(默认)

       ã€€ã€€.-version输出版本信息

       ã€€ã€€.-verbose启用详细输出

       ã€€ã€€.-force始终写入输出文件

       ã€€ã€€.使用全限定名称指定<ç±»>(例

       ã€€ã€€.如,java.lang.Object)。

       ã€€ã€€$java -version

       ã€€ã€€javaversion "1.6.0_"

       ã€€ã€€Java(TM)SE Runtime Environment (build 1.6.0_-b)

       ã€€ã€€JavaHotSpot(TM) Server VM (build .4-b, mixed mode)

       ã€€ã€€$javah

       ã€€ã€€ç”¨æ³•ï¼šjavah[选项]<ç±»>

       ã€€ã€€å…¶ä¸­[选项]包括:

       ã€€ã€€-help输出此帮助消息并退出

       ã€€ã€€-classpath<路径>用于装入类的路径

       ã€€ã€€-bootclasspath<路径>用于装入引导类的路径

       ã€€ã€€-d<目录>输出目录

       ã€€ã€€-o<文件>输出文件(只能使用-d或-o中的一个)

       ã€€ã€€-jni生成JNI样式的头文件(默认)

       ã€€ã€€-version输出版本信息

       ã€€ã€€-verbose启用详细输出

       ã€€ã€€-force始终写入输出文件

       ã€€ã€€ä½¿ç”¨å…¨é™å®šåç§°æŒ‡å®š<ç±»>(例

       ã€€ã€€å¦‚,java.lang.Object)。2.2.安装android应用程序开发环境

       ã€€ã€€ubuntu下安装android应用程序开发环境与windows类似,依次安装好以下软件即可:

       ã€€ã€€ï¼ˆ1)Eclipse

       ã€€ã€€ï¼ˆ2)ADT

       ã€€ã€€ï¼ˆ3)AndroidSDK

       ã€€ã€€ä¸Žwindows下安装唯一不同的一点是,下载这些软件的时候要下载Linux版本的安装包。

       ã€€ã€€å®‰è£…好以上android应用程序的开发环境后,还可以选择是否需要配置emulator和adb工具的环境变量,以方便在进行JNI开发的时候使用。配置步骤如下:

       ã€€ã€€æŠŠemulator所在目录android-sdk-linux/tools以及adb所在目录android-sdk-linux/platform-tools添加到环境变量中,android-sdk-linux指androidsdk安装包android-sdk_rxx-linux的解压目录。

       ã€€ã€€[plain] view plaincopyprint?

       ã€€ã€€.$sudo vim /etc/profile

       ã€€ã€€.exportPATH=~/software/android/android-sdk-linux/tools:$PATH

       ã€€ã€€. exportPATH=~/software/android/android-sdk-linux/platform-tools:$PATH

       ã€€ã€€$sudo vim /etc/profile

       ã€€ã€€exportPATH=~/software/android/android-sdk-linux/tools:$PATH

       ã€€ã€€exportPATH=~/software/android/android-sdk-linux/platform-tools:$PATH

       ã€€ã€€ç¼–辑完毕后退出,并重启生效。

       ã€€ã€€2.3.安装NDK

       ã€€ã€€NDK是由android提供的编译android本地代码的一个工具。

       ã€€ã€€ï¼ˆ1)从androidndk官网/sdk/ndk/index.html下载ndk,目前最新版本为android-ndk-r6b-linux-x.tar.bz2.

       ã€€ã€€ï¼ˆ2)解压ndk到工作目录:

       ã€€ã€€[plain] view plaincopyprint?

       ã€€ã€€.$tar -xvf android-ndk-r6b-linux-x.tar.bz2

       ã€€ã€€.$sudo mv android-ndk-r6b /usr/local/ndk

       ã€€ã€€$tar -xvf android-ndk-r6b-linux-x.tar.bz2

       ã€€ã€€$sudo mv android-ndk-r6b /usr/local/ndk

       ã€€ã€€ï¼ˆ3)设置ndk环境变量

       ã€€ã€€[plain] view plaincopyprint?

       ã€€ã€€.$sudo vim /etc/profile

       ã€€ã€€.exportPATH=/usr/local/ndk:$PATH

       ã€€ã€€$sudo vim /etc/profile

       ã€€ã€€exportPATH=/usr/local/ndk:$PATH

       ã€€ã€€ç¼–辑完毕后保存退出,并重启生效

       ã€€ã€€ï¼ˆ4)验证安装

       ã€€ã€€[plain] view plaincopyprint?

       ã€€ã€€.$ cd/usr/local/ndk/samples/hello-jni/

       ã€€ã€€.$ ndk-build

       ã€€ã€€.Gdbserver : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver

       ã€€ã€€.Gdbsetup : libs/armeabi/gdb.setup

       ã€€ã€€.Install : libhello-jni.so => libs/armeabi/libhello-jni.so

       ã€€ã€€$ cd/usr/local/ndk/samples/hello-jni/

       ã€€ã€€$ ndk-build

       ã€€ã€€Gdbserver : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver

       ã€€ã€€Gdbsetup : libs/armeabi/gdb.setup

       ã€€ã€€Install : libhello-jni.so => libs/armeabi/libhello-jni.so

       ã€€ã€€3.JNI实现

       ã€€ã€€æˆ‘们需要定义一个符合JNI接口规范的c/c++接口,这个接口不用太复杂,例如输出一个字符串。接下来,则需要把c/c++接口的代码文件编译成共享库(动态库).so文件,并放到模拟器的相关目录下。最后,启动Java应用程序,就可以看到最终效果了。

       ã€€ã€€3.1.编写Java应用程序代码

       ã€€ã€€ï¼ˆ1)启动Eclipse,新建android工程

       ã€€ã€€Project:JNITest

       ã€€ã€€Package:org.tonny.jni

       ã€€ã€€Activity:JNITest

       ã€€ã€€ï¼ˆ2)编辑资源文件

       ã€€ã€€ç¼–辑res/values/strings.xml文件如下:

       ã€€ã€€

       ã€€ã€€ç¼–辑res/layout/main.xml文件

       ã€€ã€€æˆ‘们在主界面上添加了一个EditText控件和一个Button控件。

       ã€€ã€€ï¼ˆ3)编辑JNITest.java文件

       ã€€

       ã€€ã€€static表示在系统第一次加载类的时候,先执行这一段代码,在这里表示加载动态库libJNITest.so文件。

       ã€€ã€€å†çœ‹è¿™ä¸€æ®µï¼š

       ã€€ã€€[java] view plaincopyprint?

       ã€€ã€€.privatenativeString GetReply();

       ã€€ã€€privatenativeString GetReply();

       ã€€ã€€native表示这个方法由本地代码定义,需要通过jni接口调用本地c/c++代码。

       ã€€ã€€[java] view plaincopyprint?

       ã€€ã€€.publicvoidonClick(View arg0) {

       ã€€ã€€.edtName.setText(reply);

       ã€€ã€€.}

       ã€€ã€€publicvoidonClick(View arg0) {

       ã€€ã€€edtName.setText(reply);

       ã€€ã€€}

       ã€€ã€€è¿™æ®µä»£ç è¡¨ç¤ºç‚¹å‡»æŒ‰é’®åŽï¼ŒæŠŠnative方法的返回的字符串显示到EditText控件。

       ã€€ã€€ï¼ˆ4)编译工程,生成.class文件。

       ã€€ã€€3.2.用javah工具生成符合JNI规范的c语言头文件

       ã€€ã€€åœ¨ç»ˆç«¯ä¸­ï¼Œè¿›å…¥android工程所在的bin目录

       ã€€ã€€[plain] view plaincopyprint?

       ã€€ã€€.$cd ~/project/Android/JNITest/bin

       ã€€ã€€$cd ~/project/Android/JNITest/bin

       ã€€ã€€æˆ‘们用ls命令查看,可以看到bin目录下有个classes目录,其目录结构为classes/org/tonny/jni,即classes的子目录结构是android工程的包名org.tonny.jni。请注意,下面我们准备执行javah命令的时候,必须进入到org/tonny/jni的上级目录,即classes目录,否则javah会提示找不到相关的java类。

       ã€€ã€€ä¸‹é¢ç»§ç»­ï¼š

       ã€€ã€€[plain] view plaincopyprint?

       ã€€ã€€.$cd classes

       ã€€ã€€.$javah org.tonny.jni.JNITest

       ã€€ã€€.$ls

       ã€€ã€€.org org_tonny_jni_JNITest.h

       ã€€ã€€$cd classes

       ã€€ã€€$javah org.tonny.jni.JNITest

       ã€€ã€€$ls

       ã€€ã€€org org_tonny_jni_JNITest.h

       ã€€ã€€æ‰§è¡Œjavahorg.tonny.jni.JNITest命令,在classes目录下会生成org_tonny_jni_JNITest.h头文件。如果不进入到classes目录下的话,也可以这样:

       ã€€ã€€[plain] view plaincopyprint?

       ã€€ã€€.$javah -classpath ~/project/Android/JNITest/bin/classesorg.tonny.jni.JNITest

       ã€€ã€€$javah -classpath ~/project/Android/JNITest/bin/classesorg.tonny.jni.JNITest

       ã€€ã€€-classpath 参数表示装载类的目录。

       ã€€ã€€3.3.编写c/c++代码

       ã€€ã€€ç”Ÿæˆorg_tonny_jni_JNITest.h头文件后,我们就可以编写相应的函数代码了。下面在android工程目录下新建jni目录,即~/project/Android/JNITest/jni,把org_tonny_jni_JNITest.h头文件拷贝到jni目录下,并在jni目录下新建org_tonny_jni_JNITest.c文件,编辑代码如下:

       ã€€ã€€[cpp] view plaincopyprint?

       ã€€ã€€.#include<jni.h>

       ã€€ã€€.#include<string.h>

       ã€€ã€€.#include"org_tonny_jni_JNITest.h"

       ã€€ã€€.

       ã€€ã€€.

       ã€€ã€€.JNIEXPORTjstring JNICALLJava_org_tonny_jni_JNITest_GetReply

       ã€€ã€€.(JNIEnv *env, jobject obj){

       ã€€ã€€.return(*env)->NewStringUTF(env,(char*)"Hello,JNITest");

       ã€€ã€€.}

       ã€€ã€€#include<jni.h>

       ã€€ã€€#include<string.h>

       ã€€ã€€#include"org_tonny_jni_JNITest.h"

       ã€€ã€€JNIEXPORTjstring JNICALLJava_org_tonny_jni_JNITest_GetReply

       ã€€ã€€(JNIEnv *env, jobject obj){

       ã€€ã€€return(*env)->NewStringUTF(env,(char*)"Hello,JNITest");

       ã€€ã€€}

       ã€€ã€€æˆ‘们可以看到,该函数的实现相当简单,返回一个字符串为:"Hello,JNITest"

       ã€€ã€€3.4.编写Android.mk文件

       ã€€ã€€åœ¨~/project/Android/JNITest/jni目录下新建Android.mk文件,android可以根据这个文件的编译参数编译模块。编辑Android.mk文件如下:

       ã€€ã€€[plain] view plaincopyprint?

       ã€€ã€€.LOCAL_PATH:= $(call my-dir)

       ã€€ã€€.include$(CLEAR_VARS)

       ã€€ã€€.LOCAL_MODULE := libJNITest

       ã€€ã€€.LOCAL_SRC_FILES:= org_tonny_jni_JNITest.c

       ã€€ã€€.include$(BUILD_SHARED_LIBRARY)

       ã€€ã€€LOCAL_PATH:= $(call my-dir)

       ã€€ã€€include$(CLEAR_VARS)

       ã€€ã€€LOCAL_MODULE := libJNITest

       ã€€ã€€LOCAL_SRC_FILES:= org_tonny_jni_JNITest.c

       ã€€ã€€include$(BUILD_SHARED_LIBRARY)

       ã€€ã€€LOCAL_MODULE表示编译的动态库名称

       ã€€ã€€LOCAL_SRC_FILES 表示源代码文件

       ã€€ã€€3.5.用ndk工具编译并生成.so文件

       ã€€ã€€è¿›å…¥åˆ°JNITest的工程目录,执行ndk-build命令即可生成libJNITest.so文件。

       ã€€ã€€[plain] view plaincopyprint?

       ã€€ã€€.$cd ~/project/Android/JNITest/

       ã€€ã€€.$ndk-build

       ã€€ã€€.Invalidattribute name:

       ã€€ã€€.package

       ã€€ã€€.Install : libJNITest.so => libs/armeabi/libJNITest.so

       ã€€ã€€$cd ~/project/Android/JNITest/

       ã€€ã€€$ndk-build

       ã€€ã€€Invalidattribute name:

       ã€€ã€€package

       ã€€ã€€Install : libJNITest.so => libs/armeabi/libJNITest.so

       ã€€ã€€å¯ä»¥çœ‹åˆ°ï¼Œåœ¨å·¥ç¨‹ç›®å½•çš„libs/armeabi目录下生成了libJNITest.so文件。

       ã€€ã€€3.6.在模拟器上运行

       ã€€ã€€ï¼ˆ1)首先,我们把android模拟器启动起来。进入到emulator所在目录,执行emulator命令:

       ã€€ã€€[plain] view plaincopyprint?

       ã€€ã€€.$cd ~/software/android/android-sdk-linux/tools

       ã€€ã€€.$./emulator @AVD-2.3.3-V -partition-size

       ã€€ã€€$cd ~/software/android/android-sdk-linux/tools

       ã€€ã€€$./emulator @AVD-2.3.3-V -partition-size

       ã€€ã€€AVD-2.3.3-V表示你的模拟器名称,与在Eclipse->AVDManager下的AVDName对应,-partition-size表示模拟器的存储设备容量。

       ã€€ã€€ï¼ˆ2)接下来,我们需要把libJNITest.so文件拷贝到模拟器的/system/lib目录下,执行以下命令:

       ã€€ã€€[plain] view plaincopyprint?

       ã€€ã€€.$cd ~/project/Android/JNITest/libs/armeabi/

       ã€€ã€€.$adb remount

       ã€€ã€€.$adb push libJNITest.so /system/lib

       ã€€ã€€. KB/s ( bytes in 0.s)

       ã€€ã€€$cd ~/project/Android/JNITest/libs/armeabi/

       ã€€ã€€$adb remount

       ã€€ã€€$adb push libJNITest.so /system/lib

       ã€€ã€€ KB/s ( bytes in 0.s)

       ã€€ã€€å½“在终端上看到有 KB/s ( bytes in 0.s)传输速度等信息的时候,说明拷贝成功。

       ã€€ã€€ï¼ˆ3)在终端上执行JNITest程序,这个我们可以在Eclipse下,右键点击JNITest工程,RunAs->Android Application,即可在模拟器上启动程序

用jni写的安卓应用能被反编译吗

       åç¼–译是可以的,但是由于c语言代码的可读性本身就很大,反编译后不可能像java一样回归原来的源码的,反编译的代码时没有数据类型的,所有的数据类型,甚至指针都变成了int类型,c语言的反编译基本上就可以忽略的功效基本上就可以忽略其功效,

       å¦‚果还是想看看反编译的效果,有一个工具叫做 IDA,自己可以下载下来试试;

       å¸Œæœ›å¯¹ä½ æœ‰ç”¨ï¼Œæˆ‘是ndk吧吧主,有问题可以ndk吧留言谢谢!

音视频探索(5):JPEG格式与Libjpeg库编译移植

       libJPEG-turbo是一个强大的JPEG图像处理库,它支持JPEG格式的码编编码和解码,尤其对于Android平台,源译其底层压缩常采用libJPEG。码编然而,源译Android系统为适应低版本设备,码编github 换脸源码压缩算法非标准,源译可能导致图像质量和压缩性能的码编权衡。因此,源译本篇将介绍如何利用AS的码编Cmake工具编译libJPEG-turbo,并通过JNI/NDK技术引入哈夫曼编码以优化Android中的源译压缩质量。

       哈夫曼编码是码编一种无损压缩方法,年由Huffman提出。源译它依据字符出现概率构造编码,码编概率高的源译信息编码较短。在图像压缩中,通过计算像素概率生成Huffman码表,源码底层编码后的图像数据记录每个像素的码字,与码表对应。例如,通过构建赫夫曼树,字符集中的字符对应树的路径,形成编码。

       libJPEG-turbo中的JPEG编码与解码过程包括:分配压缩对象,设置输出和参数,vecctor源码逐行处理数据,以及解压时分配和初始化解压对象、读取数据等。其核心结构体如jpeg_compress_struct和jpeg_decompress_struct,分别用于压缩和解压缩操作。

       为了在Android上实现优化,我们需要从libjpeg-turbo源码开始,首先在CmakeLists.txt中配置项目,apijson源码然后在Java层编写JNI方法,将C++的哈夫曼编码逻辑与Java代码连接。编译后,会生成libjpegtil.so文件,将其与libjpeg.so一同引入目标项目。

Android开发中的NDK到底是什么?(详细解析+案例)

       在Android开发中,Native Development Kit (NDK)扮演着关键角色,它是GU源码一个用于快速开发C和C++动态库的工具包。NDK的主要目标是将编译后的.so文件与应用一起打包成APK,尤其适合需要JNI(Java Native Interface)技术的场景。

       NDK使用步骤如下:

       首先,配置Android NDK环境。这包括下载并解压NDK工具包到指定路径,如:/Users/Carson_Ho/Library/Android/sdk/ndk-bundle。Android Studio会自动检测并集成,无需额外手动关联。

       关联项目与NDK:在Gradle配置文件中添加必要的配置,包括local.properties、gradle.properties和build.gradle中的ndk节点,确保项目每次都能正确使用NDK。

       创建本地C++代码文件,如test.cpp。注意文件命名规则,确保Java和C++接口的兼容性。

       接着,编写Android.mk和Application.mk文件,分别指定源码编译配置和平台相关配置,放在jni文件夹中。

       执行编译命令,生成.so库文件,一般会在src/main/jniLibs目录下找到。

       在MainActivity.java和对应的布局文件中,集成并调用NDK编写的C++代码。

       对于Android Studio 2.2及以上版本,NDK的集成更为方便,只需在创建工程时按照提示配置即可,无需额外安装和配置。

更多相关资讯请点击【娱乐】频道>>>