Andriod 中JNI的簡單應用(HelloWorld)

一、JNI的主要作用:在Android中調用本地的其他語言編寫好的方法(主要是C/C++)

二、實現過程

1. 新建一個Android工程,名字隨意,這裏叫做JNIExanmple,工作空間我是放在了桌面上


2 配置NDK(Native Development Kit)的路徑

如果用AS開發過工程的話,sdk路徑肯定都是已經配置好的,如果沒有sdk就要先配置一下。重點說一下首次使用JNI時,NDK的路徑配置

a.先要下載NDk的壓縮包,這是官網的下載地址https://developer.android.com/ndk/downloads/index.html  按照自己的實際情況下載相應的版本

b.解壓,原則上來說你可以解壓到任何位置,只要記住他的路徑就好(後面會用到這個路徑),但是一般推薦的解壓位置是在sdk文件夾下,如下圖

c.解壓好之後我們回到AS中,像配置sdk一樣配置ndk路徑,首先選擇Project,然後找到local.properties文件雙擊打開

在右側仿照sdk的路徑添加ndk的路徑,就是你上面解壓ndk壓縮包的位置,下圖是我的ndk路徑(要注意路徑裏面的轉譯字符和最後的文件夾的名字)

這樣ndk路徑就已經配置好了

3.開始編寫代碼

a.Java語言方面,在MainActiviry的同級目錄下新建JniUtil的java類(類的名字隨意,不一定非要叫JniUtil,記住就好)裏面聲明一個本地的(native修飾的)方法,方法名字很重要,一定要記住(注意大小寫)寫好是這樣的


看到紅色的報錯,不要着急 ,原因是我們還沒有寫他的實現,編譯器沒有在本地找到這個方法的實現

b.根據Java的JniUtil這個類生成可以供C語言引用的.h頭文件

打開AS自帶的terminal終端(View-->tool windows-->Terminal)進入到包名的上一級目錄,我這裏是進入到java(絕對路徑C:\Users\Administrator\Desktop\JNIExample\app\src\main\java)然後用到javah這個命令(後面會解釋一下這個命令),如下圖:


回車等待運行結束,再點擊Project下的java文件夾,就會看到有jni文件夾生成,裏面包含了一個包名+類名.h的文件,這樣頭文件就生成好了。

然後將jni這個文件夾連同裏面的.h文件一起拷貝到他的上級目錄就是main文件夾下面使得jni文件夾和java文件夾同級 然後make project 就可以發現有ndk文件夾生成如下圖


c.編寫本地getNative()方法的實現,用C語言。

在jni文件夾中新建.c文件 引入頭文件是同級目錄下那個.h文件,然後裏面的內容是

#include <jnidemo_jniexample_JniUtil.h>

JNIEXPORT jstring JNICALL Java_jnidemo_jniexample_jniutil_getNative
        (JNIEnv *env,jobject obj){
    return (*env)->NewStringUTF(env,"GOOD LUCK FROM NATIVE!");
}

要注意頭文件一定和jni文件下的.h文件一致,JNICALL 後面的方法名字一定要正確  規則是 Java_包名(包名的. 變成_)_方法名,其他的東西這篇文章先不討論

d.爲這個jni文件下的module起個名字(名字隨意,自己能記住就好)並且添加multiDexEnabled true 這個屬性



然後再找到gradle.properites添加android.useDeprecatedNdk=true


e.在Android的activity中調用剛剛那個getNative()方法,在MainActivity中加載一下代碼

package jnidemo.jniexample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    static{
        System.loadLibrary("luck");//加載ndk moduleName 的庫(我認爲是加載那個ndk下面的.so文件)
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_main);
        TextView txt=(TextView)findViewById(R.id.text);
        JniUtil util=new JniUtil();
        txt.setText(util.getNative());
    }
};

f.部署一下就可以看到調用的結果了



三、關於javah命令

我們可以在命令行輸入 javah -help  查看所有的用法



解釋一下  本文用到的  javah - classpath .  -d jni  -jni  jnidemo.jniexample,JniUtil 這是複合了三個命令  -classpath .   表示引用的類在當前的目錄下,那個英文的點 代表當前的目錄(沒有官方解釋,自己是這樣理解的), -d   jni 表示在當前目錄下生成一個jni文件夾存放.h文件  如果寫成 -d  123qwe

就會生成123qwe文件夾來存儲生成的.h文件  對於-jni  包名+類名  後面寫的是全限定名稱的類名(這個一直也沒有清楚是怎麼回事,求各位指教)

參考文獻

http://www.cnblogs.com/hayabusa/p/5284004.html

http://blog.csdn.net/u014657752/article/details/48106081

http://blog.csdn.net/microsoftwin32/article/details/9968085




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章