3二、JNI調用

1.一、NDK簡介

1.一、NDK概述

NDK全稱是Native Development Kit。NDK的發佈,使「Java+C」的開發方式終於轉正,成爲官方支持的開發方式。NDK將是Android平臺支持C開發的開端。html

一、NDK優點

1.代碼的保護。因爲apk的java層代碼很容易被反編譯,而C/C++庫反編譯難度較大。
2.能夠方便地使用現存的開源庫。大部分現存的開源庫都是用C/C++代碼編寫的。
3.提升程序的執行效率。將要求高性能的應用邏輯使用C開發,從而提升應用程序的執行效率。
4.便於移植。用C/C++寫得庫能夠方便在其餘的嵌入式平臺上再次使用。java

二、NDK簡介

1.NDK是一系列工具的集合
   NDK提供了一系列的工具,幫助開發者快速開發C(或C++)的動態庫,並能自動將so和java應用一塊兒打包成apk。NDK集成了交叉編譯器,android

並提供了相應的mk文件隔離CPU、平臺、ABI等差別,開發人員只須要簡單修改mk文件(指出「哪些文件須要編譯」、「編譯特性要求」等),就能夠建立出so。windows

2.NDK提供了一份穩定、功能有限的API頭文件聲明
  Google明確聲明該API是穩定的,在後續全部版本中都穩定支持當前發佈的API。從該版本的NDK中看出,這些API支持的功能很是有限,包含有:架構

C標準庫(libc)、標準數學庫(libm)、壓縮庫(libz)、   Log庫(liblog)。app

三、NDK目錄結構

build:該目錄存放的使用NDK的mk腳本,mk腳本指定了編譯參數
docs:該目錄存放的是NDK的使用幫助文檔
platforms:這裏面存放的是與各個Android版本相關的平臺(x86,arm,mips)相關C語言庫和頭文件
prebuilt:預編譯工做目錄
samples:存放的是演示程序
sources:存放的是NDK工具鏈的C語言源碼
tests:測試相關的文件
toolchains:工具鏈,存放了三種架構的靜態庫等文件
ndk-build.cmd:Window平臺使用NDK的命令
ndk-build:Linux平臺使用NDK的命令eclipse

1.二、Jni入門

1.windows->preferences->Android->NDK(輸入ndk路徑),再肯定。工具

427130d1-7488-4a88-9017-41fb4019a0b7

2.建立Android工程JNI入門,右鍵工程,找到Android Tools->點擊add native support輸入動態庫名再肯定。性能

a49b3f93-ceef-467b-a17c-83d78f761b30

3.此時,工程目錄會出現jni文件夾,中間包含兩個文件,而且咱們還須要一些用到的頭文件jni.h等。測試

313da0e5-0a71-4337-9549-c39dd2a8346f

4.導入頭文件有兩種方式:

a)進入NDK的目錄,找到:D:\android-ndk-r10d\platforms\android-21\arch-arm\usr\include,下面有不少頭文件,直接拷貝到eclipse的jni文件夾下便可。

b)直接配置導入全部的頭文件,右鍵工程->properties->C/C++ General->Paths and Symbols->add->輸入路徑

f494a313-a8ac-430f-8052-6ba9f63e6931

總結:NDK版本下有三種不一樣的架構:

f77a1efe-94be-475a-b346-90316a753621

5.在MainActivity中定義native方法

433e0c1e-f90d-4fe2-ae76-b68dba0ce189

6.在hello.cpp或hello.c等源文件下輸入以下代碼,其中的語法便不敘述

03be4c2b-3af0-46c6-b4fe-b3c1eca2caa4

7.C代碼中的命名規則(敘)

這裏的命名規則指用於跟java文件中native方法對應的C語言方法,而C語言中的其餘方法命名只要符合C語言規則就行。
jstring Java_com_itheima_jnihello_MainActivity_helloC(JNIEnv* env, jobject obj) 中,jstring是方法返回值類型,咱們能夠把jstring當作是java中String跟

C語言中char*類型的一箇中間轉換類型,java跟C語言的數據類型是不同的,他們之間要想互相調用就必須經過一種中介來實現,這個中介就是在jni.h頭文件中定義的。

關於更多的轉換類型,在本文檔的第2章會有更詳細的說明。方法名第一個字母必須是Java,首單詞大寫,而後下劃線_,而後是將該方法所在的包、類、方法用「_」鏈接起來,

好比com.itheima.jnihello.MainActivity類中的helloC方法,轉變成C語言中的方法名爲Java_com_itheima_jnihello_MainActivity_helloC。方法的形參有兩個是必須的也就是

無論java中的方法是否有形參,可是C語言中對應的方法必須有JNIEnv* env,和jobject obj,若是java方法中還用其餘形參,那麼在C語言中嚴格按照順序排在jobject obj參數

的後面便可。上面的env表明指向JVM的指針,obj是調用該方法的java對象。

8.首先查看NDK命令是否設置了環境變量,未設置則在Path中加入:D:\android-ndk-r10d

2f01efa8-784e-4b6b-9894-cc396c02c137

9.咱們須要在工程中的jni目錄中添加Android.mk配置文件。

8a89a679-a379-4fbf-9668-d4f654af6e1c

10.在cmd中,將當前目錄切換到hello.c所在目錄,而後從新執行ndk-build.cmd命令,此次成功編譯

489add4a-fb43-4867-9194-a6ff0df45c29

11.發如今libs目錄中多了兩個文件夾armeabi和x86,這兩個文件夾下分別包含了一個libhello.so動態連接庫。這也表明着當前工程中的動態庫支持arm架構和x86架構的cpu。

31480fea-2bb8-4790-b6b5-2c9cb1a62e24

12.可能你的並無同時生成這兩個文件,是由於個人工程中引入了Application.mk文件,所以你須要在jni文件夾下引入該文件。

6dcb7048-6916-45fd-a142-210c8840a2be

注:該清單其實只有一行內容,第一行是註釋。APP_ABI參數指定要生成的目標文件支持的平臺都有哪些,默認是armeabi若是想支持多個平臺只須要空一格而後寫出其餘平臺名字便可。

13.在MainActivity中調用C或C++語言

3c0cff67-19ae-44b2-a8ba-eca49e39124e

14.每次運行工程就會編譯一次so文件,若是咱們調用了外部so庫的時候,編譯時會自動刪除外部so庫。解決方法能夠配置預編譯或修改配置文件

1.百度搜索:android ndk如何取消"add native support" http://jingyan.baidu.com/article/380abd0a7309181d91192c55.html

2.配置預編譯文件

libappsign.so has text relocations. This is wasting memory and is a security risk. Please fix.

翻譯是:這個so庫存在文字搬遷,這是一種消耗內存的操做,請修復。

致使這個問題產生的緣由是由於使用了低版本的NDK編譯的so文件致使的,是NDK中的一個bug。(目前找不到合理的解釋)

相關文章
相關標籤/搜索