JNI初探

NDK產(chǎn)生背景

Android平臺從誕生起,就已經(jīng)支持C、C++開發(fā)。眾所周知,Android的SDK基于Java實(shí)現(xiàn),這意味著基于Android SDK進(jìn)行開發(fā)的第三方應(yīng)用都必須使用Java語言。但這并不等同于“第三方應(yīng)用只能使用Java”。在Android SDK首次發(fā)布時(shí),Google就宣稱其虛擬機(jī)Dalvik支持JNI編程方式,也就是第三方應(yīng)用完全可以通過JNI調(diào)用自己的C動態(tài)庫,即在Android平臺上,“Java+C”的編程方式是一直都可以實(shí)現(xiàn)的。

不過,Google也表示,使用原生SDK編程相比Dalvik虛擬機(jī)也有一些劣勢,Android SDK文檔里,找不到任何JNI方面的幫助。即使第三方應(yīng)用開發(fā)者使用JNI完成了自己的C動態(tài)鏈接庫(so)開發(fā),但是so如何和應(yīng)用程序一起打包成apk并發(fā)布?這里面也存在技術(shù)障礙。比如程序更加復(fù)雜,兼容性難以保障,無法訪問Framework API,Debug難度更大等。開發(fā)者需要自行斟酌使用。

于是NDK就應(yīng)運(yùn)而生了。NDK全稱是Native Development Kit。

NDK的發(fā)布,使“Java+C”的開發(fā)方式終于轉(zhuǎn)正,成為官方支持的開發(fā)方式。NDK將是Android平臺支持C開發(fā)的開端。

為什么使用NDK

  1. 代碼的保護(hù)。由于apk的java層代碼很容易被反編譯,而C/C++庫反匯難度較大。
  2. 可以方便地使用現(xiàn)存的開源庫。大部分現(xiàn)存的開源庫都是用C/C++代碼編寫的。
  3. 提高程序的執(zhí)行效率。將要求高性能的應(yīng)用邏輯使用C開發(fā),從而提高應(yīng)用程序的執(zhí)行效率。
  4. 便于移植。用C/C++寫得庫可以方便在其他的嵌入式平臺上再次使用。

配置環(huán)境

  1. 下載NDK,NDK下載路徑。
    Windows下的是一個(gè)自解壓文件,下載完成后雙擊運(yùn)行,文件會自解壓到當(dāng)前目錄,記住該目錄地址,配置AndroidStudio時(shí)需要使用到這個(gè)地址

  2. 打開AndroidStudio,F(xiàn)ile -> Project Structure打開對話框,在對話框中輸入NDK路徑(上面的解壓路徑)

配置NDK路徑.pic

開啟NDK之旅

1.新建JNIDemo工程,打開MainActivity.java文件,在類內(nèi)輸入下面代碼后,Build -> Make Project

public native String getStringFromNative();

2.在Terminal輸入命令

cd app\src\main
javah -d jni -classpath C:\AndroidSdk\platforms\android-23\android.jar;..\..\build\intermediates\classes\debug com.sentu.jnidemo.MainActivity

就會發(fā)現(xiàn)在main目錄下多了一個(gè)jni文件夾,里面有生成好的頭文件

3.在jni目錄下創(chuàng)建一個(gè).c文件,實(shí)現(xiàn)頭文件里聲明的方法

#include "com_sentu_jnidemo_MainActivity.h"

JNIEXPORT jstring JNICALL Java_com_sentu_jnidemo_MainActivity_getStringFromNative(JNIEnv *env, jobject obj) {
    return (*env)->NewStringUTF(env, "I'm comes from to Native Function!");
}

4.在 local.properties 文件中設(shè)置ndk的路徑

ndk.dir=C\:\\AndroidSdk\\android-ndk-r10e

5.在MainActivity.java文件中添加如下代碼

public class MainActivity extends Activity {

    public native String getStringFromNative();

    static {
        System.loadLibrary("MyJni");
    }

    TextView info;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        info = (TextView) findViewById(R.id.info);
        info.setText(getStringFromNative());
    }
}

6.運(yùn)行,查看效果

這個(gè)時(shí)候可能會出現(xiàn)一個(gè)問題

Error:(13, 0) Error: NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin. For details, see http://tools.android.com/tech-docs/new-build-system/gradle-experimental. Set "android.useDeprecatedNdk=true" in gradle.properties to continue using the current NDK integration.

解決方案: 在gradle.properties中添加android.useDeprecatedNdk=true

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容