成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Android架構師之路-JNI與NDK編程知識基礎詳解(c++音視頻編碼基礎)

開發 前端
NDK提供了一系列的工具,幫助開發者快速開發C(或C++)的動態庫,并能自動將so和java應用一起打包成apk。這些工具對開發者的幫助是巨大的。

[[412121]]

前沿小記

  • 1、Android架構師要學習的知識點有很多,后面我會總結下關于Android開發中jni和ndk開發的知識點,當前基礎是越牢固越好,后期學習起來就不會太累,一點就懂;
  • 2、今天我們就來總結下jni和ndk的基礎知識點;
  • 3、Android 平臺從一開就已經支持了C/C++了。我們知道Android的SDK主要是基于Java的,所以導致了在用Android SDK進行開發的工程師們都必須使用Java語言。不過,Google從一開始就說明Android也支持JNI編程方式,也就是第三方應用完成可以通過JNI調用自己的C動態度;

一、什么是ndk

  • NDK提供了一系列的工具,幫助開發者快速開發C(或C++)的動態庫,并能自動將so和java應用一起打包成apk。這些工具對開發者的幫助是巨大的;
  • NDK集成了交叉編譯器,并提供了相應的mk文件隔離CPU、平臺、ABI等差異,開發人員只需要簡單修改mk文件(指出“哪些文件需要編譯”、“編譯特性要求”等),就可以創建出so;
  • NDK可以自動地將so和Java應用一起打包,極大地減輕了開發人員的打包工作;
  • NDK提供了一份穩定、功能有限的API頭文件聲明;Google明確聲明該API是穩定的,在后續所有版本中都穩定支持當前發布的API。從該版本的NDK中看出,這些API支持的功能非常有限,包含有:C標準庫(libc)、標準數學庫(libm)、壓縮庫(libz)、Log庫(liblog);
  • NDK的發布,使“Java+C”的開發方式終于轉正,成為官方支持的開發方式;
  • 使用NDK,我們可以將要求高性能的應用邏輯使用C開發,從而提高應用程序的執行效率;
  • 使用NDK,我們可以將需要保密的應用邏輯使用C開發。畢竟,Java包都是可以反編譯的;
  • NDK促使專業so組件商的出現:比如視頻庫的編譯、音頻庫、圖片庫濾鏡等等;
  • NDK將使Android平臺支持C開發的開端;NDK提供了的開發工具集合,使開發人員可以便捷地開發、發布C組件。同時,Google承諾在NDK后續版本中提高“可調式”能力,即提供遠程的gdb工具,使我們可以便捷地調試C源碼;

二、為什么使用NDK

在平臺之間移植其應用;

重復使用現在庫,或者提供其自己的庫重復使用;

在某些情況下提性能,特別是像游戲這種計算密集型應用;

使用第三方庫,現在許多第三方庫都是由C/C++庫編寫的,比如Ffmpeg這樣庫;

不依賴于Dalvik Java虛擬機的設計;

代碼的保護。由于APK的Java層代碼很容易被反編譯,而C/C++庫反編譯難度大;

三、jni詳解

1、jni是什么?以及和ndk關系

  • JNI,全稱為Java Native Interface,即Java本地接口,JNI是Java調用Native 語言的一種特性。通過JNI可以使得Java與C/C++機型交互。即可以在Java代碼中調用C/C++等語言的代碼或者在C/C++代碼中調用Java代碼。由于JNI是JVM規范的一部分,因此可以將我們寫的JNI的程序在任何實現了JNI規范的Java虛擬機中運行;
  • 在Android Framework中,需要提供一種媒介或 橋梁,將Java層(上層)與C/C++層(下層)有機的聯系起來,使得他們互相協調完成某些任務。而充當這種媒介的就是Java本地接口(JNI,Java Native Interface);
  • JNI提供一些列的接口,允許Java類與C/C++等本地編輯語言(在JNI中,這些語言被稱為 本地語言)編寫的應用 程序、模塊 、庫進行交互操作。比如,在Java類中使用C語言庫中的函數或在C語言中使用 Java類庫,都需要借助JNI;
  • Android NDK是一個開發工具集,提供一系列工具快速開發C/C++的動態庫,并能自動將 .so/.dll 和 Java 應用一起打包到Apk;NDK提供工具可以方便JNI調用C/C++,而且提供了交叉編譯器可以修改.mk文件生成特定CPU平臺的動態庫,并能將so和java應用一起打包到apk中;簡單說就是JNI負責Java與C/C++進行互相操作,NDK提供工具方便在Android平臺使用JNI;

2、JNI開發流程的步驟

圖片
  • 在Java中先聲明一個native方法;
  • 編譯Java源文件javac得到.class文件;
  • 通過javah -jni命令導出JNI的.h頭文件;
  • 使用Java需要交互的本地代碼,實現在Java中聲明的Native方法;
  • 將本地代碼編譯成動態庫(Windows系統下是.dll文件,如果是Linux系統下是.so文件,如果是Mac系統下是.jnilib);
  • 通過Java命令執行Java程序,最終實現Java調用本地代碼;
圖片

3、 JNI數據結構

圖片

JNI函數表的組成就像C++的虛函數表。虛擬機可以運行多張函數表,舉例來說,一張調試函數表,另一張是調用函數表。JNI接口指針僅在當前線程中起作用。這意味著指針不能從一個線程進入另一個線程,然而,可以在不同的咸亨中調用本地方法;

  1. jdouble test (JNIEnv *env, jobject obj, jint i, jstring s) 
  2.      const char *str = (*env)->GetStringUTFChars(env, s, 0);  
  3.      (*env)->ReleaseStringUTFChars(env, s, str);  
  4.      return 10; 
圖片

JNI有自己的原始數據類型和數據引用類型如下

圖片

四、jni交互原理詳解

1、JavaVM

JavaVM是Java虛擬機在JNI層的代表,JNI全局僅僅有一個JavaVM結構中封裝了一些函數指針(或叫函數表結構),JavaVM中封裝的這些函數指針主要是對JVM操作接口。另外,在C和C++中的JavaVM的定義有所不同,在C中JavaVM是JNIInvokeInterface_類型指針,而在C++中有對JNIInvokeInterface_進行了一次封裝,比C中少了一個參數,這也是為什么JNI代碼更推薦使用C++來編寫的原因;

2、JNIEnv

JNIEnv是一個線程相關的結構體,該結構體代表了Java在本線程的執行環境

JNIEnv是當前Java線程的執行環境,一個JVM對應一個JavaVM結構,而一個JVM中可能創建多個Java線程,每個線程對應一個JNIEnv結構,它們保存在線程本地存儲TLS中。因此,不同的線程的JNIEnv是不同,也不能相互共享使用。JNIEnv結構也是一個函數表,在本地代碼中通過JNIEnv的函數表來操作Java數據或者調用Java方法。也就是說,只要在本地代碼中拿到了JNIEnv結構,就可以在本地代碼中調用Java代碼;

調用Java 函數:JNIEnv代表了Java執行環境,能夠使用JNIEnv調用Java中的代碼;

操作Java代碼:Java對象傳入JNI層就是jobject對象,需要使用JNIEnv來操作這個Java對象;

3、JNIEnv和JavaVM的區別

  • JavaVM:JavaVM是Java虛擬機在JNI層的代表,JNI全局僅僅有一個;
  • JNIEnv:JavaVM 在線程中的代碼,每個線程都有一個,JNI可能有非常多個JNIEnv;

4、JNIEnv與線程

  • JNIEnv是線程相關的,即在每一個線程中都有一個JNIEnv指針,每個JNIEnv都是線程專有的,其他線程不能使用本線程中的JNIEnv,即線程A不能調用線程B的JNIEnv,所以JNIEnv不能跨線程;
  • JNIEnv只在當前線程有效:JNIEnv僅僅在當前線程有效;
  • JNIEnv不能在線程之間進行傳遞,在同一個線程中,多次調用JNI層方便,傳入的JNIEnv是同樣的;
  • 本地方法匹配多個JNIEnv:在Java層定義的本地方法,能夠在不同的線程調用,因此能夠接受不同的JNIEnv;

5、JNIEnv結構

圖片

6、JNIEnv相關的常用函數

  1. 創建Java中的對象 
  2.     jobject     (*NewObject)(JNIEnv*, jclass, jmethodID, ...); 
  3.     jobject     (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list); 
  4.     jobject     (*NewObjectA)(JNIEnv*, jclass, jmethodID, const jvalue*); 
  5. 字符串相關 
  6.   jstring     (*NewString)(JNIEnv*, const jchar*, jsize); 
  7.     jsize       (*GetStringLength)(JNIEnv*, jstring); 
  8.     const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*); 
  9.     void        (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*); 
  10.     jstring     (*NewStringUTF)(JNIEnv*, const char*); 
  11.     jsize       (*GetStringUTFLength)(JNIEnv*, jstring); 
  12.     /* JNI spec says this returns const jbyte*, but that's inconsistent */ 
  13.     const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*); 
  14. 獲取數組相關 
  15.  jsize GetArrayLength(jarray array) 
  16. return functions->GetArrayLength(this, array); } 
  17. jobject GetObjectArrayElement(JNIEnv *env, 
  18. jobjectArray array, jsize index); 

總結:

  • 以上是學習jni的基礎知識點,必須理解的,不懂的就問就學;
  • jni還有很多知識點,比如動態注冊,靜態注冊等等;
  • 要學習一點c語言和c++的基礎知識點,后面會講到總結。

本文轉載自微信公眾號「Android開發編程」,可以通過以下二維碼關注。轉載本文請聯系Android開發編程公眾號。

 

責任編輯:姜華 來源: Android開發編程
相關推薦

2021-07-26 05:26:54

Androidc++java

2023-03-03 15:40:43

抖音視頻編碼器

2011-07-13 18:24:18

C++

2010-02-01 16:13:15

C++繼承

2015-06-10 11:22:41

云計算云架構師

2013-04-19 15:12:17

架構師WEB架構師

2010-01-19 10:16:40

C++程序

2010-01-19 14:45:35

C++語言

2010-02-02 09:43:27

C++存儲區域

2011-07-15 01:38:56

C++this指針

2010-02-05 17:00:06

C++單例模式

2020-09-30 09:47:17

架構

2009-08-24 18:22:05

C# 泛型編程

2022-06-20 05:59:35

5G技術音視頻技術安卓系統

2011-07-14 17:37:02

C++面向對象編程思想

2011-07-14 17:24:10

C++面向對象思想

2009-08-21 17:19:36

C#網絡編程入門

2012-04-09 09:41:24

WEB架構師

2009-04-17 14:22:40

XPathXML基礎

2019-07-23 18:15:26

技術大數據數據庫
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美高清dvd | 日韩精品1区2区3区 成人黄页在线观看 | 亚洲精品一区在线观看 | 91视频a| 日本福利一区 | 91精品国产91 | 久久国产一区二区 | 亚洲v日韩v综合v精品v | 成人三级av| www久久久 | 成人亚洲精品 | 国产精品美女在线观看 | 视频一区二区三区中文字幕 | 香蕉av免费| 999久久久久久久久 国产欧美在线观看 | 亚洲国产一区二区三区 | 国产一级淫片免费视频 | 一区二区三区在线电影 | 亚洲精品天堂 | 福利片在线观看 | 亚洲高清视频在线观看 | 尤物在线视频 | 欧美午夜精品久久久久免费视 | 久久国产一区二区三区 | 看一级毛片 | 国产日韩欧美电影 | 91黄在线观看 | 热re99久久精品国产99热 | 天堂视频中文在线 | 久久精品中文 | 国产激情视频在线 | 久久久成人精品 | 亚洲成人精品国产 | 99九色 | 午夜免费电影院 | 久久国产精品久久久久久久久久 | 中文字幕亚洲专区 | 国产免费自拍 | 91豆花视频| 欧美高清性xxxxhdvideosex | 亚洲免费成人 |