Android中JNI使用詳解(2)---Android Studio中SO檔案生成
上一篇寫到過在Android Studio中配置NDK環境位址:Android Studio中NDK環境配置
這篇文章講解在Android Studio中如何使用NDK生成so檔案
1、首先建立一個Android Studio項目
建立 jni 目錄:在項目中右鍵 new->folder->jni folder 選擇 main 檔案夾點選 finish ,這時候在項目中 app->main 生成了 jni 目錄,當然也可以手動建立。
2、建立native方法
在項目中建立 com.jni.test 包,在包中建立 NativeUtil.class 檔案 , 添加 native 方法 ;
package com.jni.test;
/**
* Created by Shaofeng.lan on 2016/7/12.
*/
public class NativeUtil {
public static native String getJniString();
}
3、生成.h檔案
3.1、在Terminal(位置在Android Studio下面)輸入指令cd app/src/main/java進入app java路徑。
D:\AndroidStudio\NdkDemo>cd app/src/main/java
3.2、輸入指令執行javah +【包名+檔案名】如:javah com.jni.test.NativeUtil。
D:\AndroidStudio\NdkDemo\app\src\main\java>javah com.jni.test.NativeUtil
3.3、然後在java目錄下可以看見生成的對應.h【com_jni_test_NativeUtil.h】檔案。
com_jni_test_NativeUtil.h代碼:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jni_test_NativeUtil */
#ifndef _Included_com_jni_test_NativeUtil
#define _Included_com_jni_test_NativeUtil
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_jni_test_NativeUtil
* Method: getJniString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_jni_test_NativeUtil_getJniString
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
4、編寫.c檔案
将生成的.h檔案拷貝到jni檔案夾中,并重命名為test.c并實作native方法
test.c代碼:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jni_test_NativeUtil */
#ifndef _Included_com_jni_test_NativeUtil
#define _Included_com_jni_test_NativeUtil
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_jni_test_NativeUtil
* Method: getJniString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_jni_test_NativeUtil_getJniString
(JNIEnv * env, jclass jobj){
return (*env)->NewStringUTF(env,"Hello JNI!");
}
#ifdef __cplusplus
}
#endif
#endif
5、配置jni環境
在app的build.gradle檔案中,在defaultConfig節點添加一下代碼
ndk {
moduleName "JniDemo"
ldLibs "log", "z", "m"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
整體代碼如下:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.example.shaofenglan.ndkdemo"
minSdkVersion 9
targetSdkVersion 23
versionCode 1
versionName "1.0"
ndk {
moduleName "JniDemo"
ldLibs "log", "z", "m"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
}
在project的gradle.properties目錄下添加:
android.useDeprecatedNdk=true
檢視project的local.properties目錄是否有配置ndk環境:
ndk.dir=【NDK路徑】
6、生成so檔案
執行Build->Rebuild Project就可以編譯出SO 檔案,如圖:
在app -> build -> intermediates -> ndk -> debug -> lib 中可以看到生成的 so檔案,如圖:
7、調用so檔案
加載靜态庫:
static {
System.loadLibrary("JniDemo");
}
然後調用native方法,代碼如下:
package com.example.shaofenglan.ndkdemo;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import com.jni.test.NativeUtil;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e("TAG", NativeUtil.getJniString());
}
static {
System.loadLibrary("JniDemo");
}
}
控制台列印: