-
1. JNI에서 사용할 java쪽 native method를 생성한다.
사용하는 클래스에 넣어도 상관없고, 아예 JNI전용 클래스를 만들어도 상관없는데,
중요한건 메소드에 달린 native 키워드.
package kr.example.admin.myndktest2;
public class MyNDKModule {
public native String getMessage();
}
2. Ctrl+F9나 메뉴의 Build-Make Project를 눌러 빌드를 한번 진행해둔다.
빌드를 한번 하는 이유는, 자바 클래스 파일에서 C 헤더를 뽑아주는
javah가 .java 소스파일이 아닌 .class 바이트코드 파일을 참조하기 때문.
3. 소스쪽 디렉토리에 jni 디렉토리를 생성하고,
우측버튼 - New - Folder - JNI Folder
4. 생성된 jni 디렉토리에 javah와 class파일을 이용해서 JNI .h 헤더파일을 생성한다.
javah 명령은,
javah -classpath 클래스패스 클래스명
구조이다.
터미널에서
cd app\src\main\jni
javah.exe -classpath ..\..\..\build\intermediates\classes\debug\ kr.example.admin.myndktest2.MyNDKModule
위와 같이 하면 jni폴더에 "kr_example_admin_myndktest2_MyNDKModule.h"파일이 생성된다.
이제 C/C++ 파일을 만들어서 코딩한다.
main.c
======================================
#include "kr_example_admin_myndktest2_MyNDKModule.h"
JNIEXPORT jstring JNICALL Java_kr_example_admin_myndktest2_MyNDKModule_getMessage (JNIEnv *env, jobject obj){
return (*env)->NewStringUTF(env, "Hello World - 안녕~~~");
}
5. Build 메뉴의 Make Module 'app'를 눌러 모듈을 빌드한다.
이 상태에서 빌드를 하면 ndk를 찾을 수 없다고 오류가 발생한다.
local.properties파일의 NDK경로를 확인한다
ndk.dir=C\:\\Users\\Administrator\\AppData\\Local\\Android\\sdk\\ndk-bundle
sdk.dir=C\:\\Users\\Administrator\\AppData\\Local\\Android\\sdk
gradle.properties파일을 열어 아래의 내용을 마지막줄에 추가한다.
android.useDeprecatedNdk=true
6. Build 메뉴의 Make Module 'app'를 눌러 모듈을 다시 빌드한다.
7. 1번에서 만든 class파일을 열어 아래와 같이 수정한다.
System.loadLibrary에서 사용되는 이름은 기본적으로 모듈 이름이다.
package kr.example.admin.myndktest2;
public class MyNDKModule {
static {
System.loadLibrary("app");
}
public native String getMessage();
}
8. 라이브러리 명 (.so파일명)을 변경하고 싶다면,
모듈의 build.gradle 파일을 열어 moduleName을 정의해준다.
defaultConfig {
applicationId "kr.example.admin.myndktest2"
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
ndk{
moduleName "MyNDKModule"
}
}
moduleName을 변경하면 .so파일명도 변경되고,
System.loadLibrary()에 사용되는 이름도 변경해주어야 한다.
9. C에서 __android_log_print()를 사용했는데 빌드 중 오류가 발생한다면,
android log library를 빌드에 추가해주어야 한다.
모듈별 build.gradle에 ldLibs "log" 를 추가해 준다.
정상적으로 로그가 출력되는것을 확인할 수 있다.
ndk{
moduleName "MyNDKModule"
ldLibs "log"
}
각 c/cpp 파일에 head 추가하고
#include <android/log.h>
아래의 함수를 이용하여 로그를 출력한다.
__android_log_print("로그 타입", "로그 명", "로그 내용 및 변수 타입", 변수);
예)
#include "NativeModule.c.h"
#include <android/log.h>
JNIEXPORT jstring JNICALL Java_kr_example_admin_myndktest2_MyNDKModule_getMessage (JNIEnv *env, jobject obj){
__android_log_print(ANDROID_LOG_DEBUG, "JNI TEST","로그를 출력해보자");
return (*env)->NewStringUTF(env, "Hello World - 안녕~~~");
}
10. MainActivity를 열어 사용하는 코드를 추가한다.
textView = (TextView)findViewById(R.id.textView);
MyNDKModule jni = new MyNDKModule();
textView.setText(jni.getMessage());
11. 실행한다.....
//==========================================================================================
// 위의 4번에서 터미널을 사용하는 방법이 어렵다면
File 메뉴의 Setting으로 들어가서
Tools의 External Tools 를 선택하고 + 기호를 눌러 외부 툴을 등록한다.
Name : javah
Program : 은 버튼을 눌러 JDK\bin안의 javah.exe를 선택한다.
Parameters : -classpath $OutputPath$\ 클래스전체이름
예) -classpath $OutputPath$\ kr.example.admin.myndktest2.MyNDKModule
Working Directory : $ProjectFileDir$\app\src\main\jni
위와 같이 설정하고
프로젝트명 위에서 우측버튼 - External Tools - javah를 선택하면 헤더파일이 자동으로 생성된다.
'Android' 카테고리의 다른 글
TitleBar 없애기 (0) 2017.03.17 마시멜로 권한 획득하기 (0) 2016.03.22 볼륨 조절하기 (0) 2015.08.18 암시적 인텐트 사용 (0) 2015.07.23 댓글