[Android NDK/JNI-1A]-開發環境搭建

來源:互聯網
上載者:User

標籤:

NDK簡介

   NDK能幹什麼:NDK使得在android中,java可以調用C 函數庫。

1.Android平台從誕生起,就已經支援C、C++開發。眾所周知,Android的SDK基於Java實現,這意味著基於Android SDK進行開發的第三方應用都必須使用Java語言。但這並不等同於“第三方應用只能使用Java”。

2.在Android SDK首次發布時,Google就宣稱其虛擬機器Dalvik支援JNI編程方式,也就是第三方應用完全可以通過JNI調用自己的C動態庫,即在Android平台上,“Java+C”的編程方式是一直都可以實現的。

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

4.NDK整合了交叉編譯器,並提供了相應的mk檔案隔離CPU、平台、ABI等差異,開發人員只需要簡單修改mk檔案(指出“哪些檔案需要編譯”、“編譯特性要求”等),就可以建立出so。

5.NDK可以自動地將so和Java應用一起打包,極大地減輕了開發人員的打包工作。

6.NDK提供了一份穩定、功能有限的API標頭檔聲明

7.Google明確聲明該API是穩定的,在後續所有版本中都穩定支援當前發布的API。從該版本的NDK中看出,這些API支援的功能非常有限,包含有:C標準庫(libc)、標準數學庫(libm)、壓縮庫(libz)、Log庫(liblog)。

Today

1.NDK並不能顯著提升應用效率。我們都覺得C語言比起java來說效率要高出很多,一方面,隨著jdk的不斷更新,java的效率也隨之提高;另一方面,即便使用C語言編碼提高了應用效率,但是在java與C相互調用時平白又增大了開銷。

2.今天折騰了大半天,才編譯出自己想要的so檔案。但是android studio整合式開發環境中還沒嘗試。

3.關於Cygwin下載問題,官方放在的step.exe國內今天根本沒發弄下來,下載了一個老版本的exe,但是又不給更新。

http://www.redhat.com/services/custom/cygwin/ 在紅帽試過,雖然exe能弄下來,但是Cygwin需要的下載的檔案根本沒法下載(網速太慢,比蝸牛還慢,況且有好幾個G的)

http://mirrors.163.com/  網易開源鏡像站

http://www.cygwin.cn/site/info/show.php?IID=1003 Cygwin中文網

4.由於Java中的本地方法名稱及包路徑都是寫死在C語言中的,因此本地相關代碼不能混淆

5.項目中的JNI目錄時編寫c/c++的代碼區,執行ndk-build命令後會在libs下產生so檔案,在運行項目時,也是調用so檔案中的相關資源。

為什麼要使用NDK

java是半解釋型語言,很容易被反組譯碼後拿到原始碼檔案,在開發一些重要協議時,我們為了安全起見,使用C語言來編寫這些重要的部分,來增大系統的安全性。還有,在一些接近硬體環境下,相信大家都清楚C與java的優劣。

1.代碼的保護。由於apk的java層代碼很容易被反編譯,而C/C++庫反匯難度較大。

2.可以方便地使用現存的開源庫。大部分現存的開源庫都是用C/C++代碼編寫的。

3.提高程式的執行效率。將要求高效能的應用邏輯使用C開發,從而提高應用程式的執行效率。

4.便於移植。用C/C++寫得庫可以方便在其他的嵌入式平台上再次使用。

5.Eclipse中ndk配置

NDK開發所需要的環境

1.Android應用開發所需要的開發Integration Environment(環境變數自己百度)

2.NDK所需要的開發包(C:\java\android-ndk-r7b)

3.linux環境需要下載cygwin(C:\java\cygwin\bin)

4.配置各自的環境變數(JDK,SDK,NDK,cygwin)

JNI編碼

1.建立一個android工程

2.在工程目錄下添加名為 jni 的檔案夾(必須)如:

3.在jni檔案夾下建立你的.c和.h檔案檔案(JNI_Demo.c和JNI_Demo.h)

4.在jni檔案夾下建立名字為Android.mk檔案(檔案名稱符合命名規則都行)

5.在上述.mk檔案中加入如下代碼:

LOCAL_PATH := $(call my-dir)//當前路徑(如果你瞭解shell語言,應該可以很輕鬆的理解)include $(CLEAR_VARS)LOCAL_MODULE    := JNI_Demo //要產生的.so庫名LOCAL_SRC_FILES := JNI_Demo.c //jni檔案夾下的c檔案名稱include $(BUILD_SHARED_LIBRARY)

6.在JNI_Demo.c檔案中加入如下代碼:

#include <stdio.h>#include "JNI_Demo.h"const char keyValue[] = {    119,119,119,46,104,111,109,105,108,121,46,99,110};JNIEXPORT jbyteArray JNICALL Java_com_homily_SecurityUtil_getKeyValue  (JNIEnv *env, jclass obj){    jbyteArray kvArray = (*env)->NewByteArray(env, sizeof(keyValue));    jbyte *bytes = (*env)->GetByteArrayElements(env,kvArray,0);    int i;    for (i = 0; i < sizeof(keyValue);i++)    {        bytes[i] = (jbyte)keyValue[i];    }    (*env)->SetByteArrayRegion(env,kvArray, 0, sizeof(keyValue),bytes);    (*env)->ReleaseByteArrayElements(env,kvArray,bytes,0);    return kvArray;}

 7.在JNI_Demo.h檔案中加入如下代碼:

#include <jni.h>#ifndef _Included_com_homily_SecurityUtil#define _Included_com_homily_SecurityUtil#ifdef __cplusplusextern "C" {#endifJNIEXPORT jbyteArray JNICALL Java_com_homily_SecurityUtil_getKeyValue  (JNIEnv *, jclass);#ifdef __cplusplus}#endif#endif

8.然後就是寫C對應的Java代碼

Java_com_homily_SecurityUtil_getKeyValue

這個是Java類對應的路徑,必須以Java開頭,com.homily.SeturityUtil.java類下的getKeyValue方法。JNI橋接代碼如下:

 1 package com.homily; 2  3 public class SecurityUtil { 4     private static byte[] keyValue; 5      6     static { 7         System.loadLibrary("JNI_Demo"); 8         keyValue = getKeyValue(); 9     }  10     11     public static String getValue() {12         return new String(keyValue);13     }14     15     public static native byte[] getKeyValue();16     17 }

9.android調用代碼如下   

 1 package com.homily; 2 import android.app.Activity; 3 import android.os.Bundle; 4 import android.util.Log; 5  6 public class MainActivity extends Activity { 7      8     private static final String TAG = "MainActivity"; 9     10     @Override11     protected void onCreate(Bundle savedInstanceState) {12         super.onCreate(savedInstanceState);13         14         setContentView(R.layout.activity_main);15         String enstr = SecurityUtil.getValue();16         Log.d(TAG, "web address[" + enstr +"]");17     }18 19 }
NDK編譯結果       

1.產生so檔案

        開啟cmd,使用cd等相關命令進入該工程目錄下  ,運行下面的命令,完成後點擊右鍵重新整理下項目,在libs下面就會產生so檔案,如下:

E:\android_workspace\JNI_Demo>NDK-buildAndroid NDK: WARNING: APP_PLATFORM android-19 is larger than android:minS[armeabi] Compile thumb  : JNI_Demo <= JNI_Demo.c[armeabi] SharedLibrary  : libJNI_Demo.so[armeabi] Install        : libJNI_Demo.so => libs/armeabi/libJNI_Demo.so

so檔案如:

2.最後運行下項目,輸出日誌如下:

參考資料:

http://mobile.51cto.com/aprogram-434525.htm

http://www.cnblogs.com/devinzhang/archive/2012/02/29/2373729.html

 

[Android NDK/JNI-1A]-開發環境搭建

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.