AndroidStudio2.2 cMake方式建立jni工程

來源:互聯網
上載者:User

標籤:找不到   rom   jnicall   重要   code   執行   轉換   ctr   參數   

關於CMake:從androidStudio2.2版本開始,可以用cmake方式建立jni工程。


開啟androidStudio之後按照以下步驟:
1)File-New-New Project , 注意勾選支援c++。然後一路next一直到finish。

 


2)我這裡出現一個編譯問題;(如果沒遇到這個問題,跳過此步驟)

 

這個是因為新建立的工程,沒有預設的NDK配置;配一下即可。操作如下:
右鍵工程名,選open Module Setting 開啟這個:

然後注意紅色標記。配置好你的NDK路徑,我用的是14b這個版本。
點OK,然後androidStudio會自動編譯。

3)觀察一下自動產生的這些代碼;

這裡有一個自動產生的MainActivity.java 紅色標記的地方,就是調用的JNI。
下面的System.loadLibrary就是載入名為native-lib.so的引擎檔案(cmake方式下,在工程中看不到這個檔案,但是編譯出來的apk是有的)
上面的native方法,就是在java代碼中聲明,jni層有這麼一個方法的實現。
左邊畫圈圈的 ,點一下(或者滑鼠放在方法名上面,按住ctrl,點滑鼠左鍵),就能直接索引到cpp檔案中,這個方法的具體實現。如。

 


第一次看到這個檔案可能有點陌生,下面貼出重要代碼的註解;

#include <jni.h>#include <string>extern "C" //這一句,表示,按照C的方式去編譯,如果不加這句,可能導致找不到這個方法JNIEXPORT jstring JNICALL //這一句,表示,傳回值是一個java的string,至於JNIEXPORT ,JNICALL都是JNI的文法Java_test_hank_com_jni1011_MainActivity_stringFromJNI( // 這句,表示這個是實現JAVA類中的一個方法,java類的全名是test.hank.com.//jni1011.MainActivity,方法名為stringFromJNIJNIEnv *env,//指標對象jobject /* this */) {std::string hello = "Hello from C++";//建立string 對象,std::的寫法,std是c++標準庫,兩個冒號之後,加上string,是說這個類是c++標準庫內的string類。用這個類來建立一個string對象return env->NewStringUTF(hello.c_str());//傳回值 ,由於env是指標對象,所以要用->來調用方法,NewStringUTF() 構建一個UTF編碼的字串}

運行工程,就能看到介面中間顯示一行字串“Hello from C++”;這行字串明顯來自jni層。
android給我們建立樣本工程的時候,只告訴我們怎麼用java調用jni。但是jni回調java的過程,需要我們手動修改代碼。

4)手動修改代碼,來實現jni層調用c++層的代碼;
1-建立一個java類:JavaCaller.java ,並建立一個方法,表示這個就是讓jni層去調用的方法。

 


2-jni調用java某個對象的方法,也要遵循物件導向的方式,必須有該對象的引用才行。所以我們要先傳遞一個對象到jni層。
看代碼。
在java層,建立一個native方法,setJavaObject,參數為JavaCaller類的一個對象。

 


滑鼠放在方法名上,按住alt+enter,就會提示,建立一個jni方法,作為這個native的實現。
選擇建立該方法,(這裡有個坑,自動產生的這個方法,沒有extern "C" 導致編譯通不過,大概原因就是加了extern "C",就表示用c的方式去編譯,jni對接的應該還是c,所以要加上extern "C")
然後寫代碼調用這個setJavaObject方法。
接下來繼續進入jni層,這裡,我們的目的是jni層調用java類的某個方法。
所以,要在jni中寫代碼來使用傳遞進來的這個java對象。
代碼如下,有每個步驟的詳細註解:

這樣的話,調用過程就執行完畢了。
執行代碼,就會發現,日誌中有這一行。
10-11 04:23:51.112 4254-4254/test.hank.com.jni1011 D/hankzhou: param:這裡能不能放中文? - param2:真的可以放中文耶

這個就是我們在JavaCaller.java test方法中列印的日誌。說明,jni回調java的方法成功。

至此,AndroidStudio - cMake方式開發jni的樣本就完成了。
但是,有兩點需要說明一下。
1)java的類型 轉化為jni的類型存在有規律的轉化(觀察一下java層的native方法,以及jni層的c方法,兩者的參數列表。有關聯,但是寫法大不相同)

 


很抽象?那麼看圖吧。
這是java的:

 

這是jni的:

 

jni前面的兩個是幹啥的暫時不知,但是很明顯能看到3個參數都是string,到了jni這裡,就變成了jstring,這就是所謂寫法上的轉化。

2) jni回調java對象的某個方法,也是有類型轉換的;

還是看圖:
java的方法:


jni中用反射建立該方法:

 


這裡的實參,test 是方法名,保持一致。
形參以及傳回值,必須完全對應,這裡就有一個類型轉換了。
先看最後這個V,對應test方法的傳回值void。
前面的兩個 Ljava/lang/String; 對應兩個string。(多個參數,分號分隔)
這裡是void和string,那麼如果是其他類型呢?參見了上面的表格。

 

以上就是cMake方式開發jni的入門級指導。更複雜的,以後再寫。


AndroidStudio2.2 cMake方式建立jni工程

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.