본문 바로가기
프로그래밍/Android

how to use so files in Android JNI -1-

by 즉흥 2016. 8. 2.
728x90
반응형


환경


운영체제 : Windows 10

IDE : Android Studio

예제 so 파일 : OpenSSL


2부 : http://amgn.tistory.com/601


하 시발 진짜 존나 구글링하면서 개고생했다.


당연한 이야기지만 사전에 안드로이드 NDK, 안드로이드 SDK, JAVA JDK가 설치되어 있어야 함.


https://developer.android.com/ndk/guides/setup.html


나는 둘 다 D 드라이브에 저장해놨다.


안드로이드 스튜디오에서 빈 프로젝트를 생성하면 기본적으로 아래와 같이 Hello World!를 출력하게 된다.



OpenSSL과 JNI를 이용해 암호화된 Hello World!를 출력하는 과정을 블로깅함.


안드로이드 프로그래밍에 대한 사전 지식이 없어서 시발 존나 힘들었음.



1부에서는 JNI 생성방법까지, 2부에서는 OpenSSL을 안드로이드 스튜디오에서 JNI로 사용하는 방법을 올리도록 하겠다.




1. 프로젝트 생성



우선 안드로이드 스튜디오에서 빈 프로젝트로 프로젝트 생성.



2. External Tools 설정



File -> Settings에 가면 위와 같은 창이 뜬다. 거기서 External Tools 누르면 됨.


그리고 + 이미지를 눌러 툴 두 개를 등록한다.


내 기준으로 javah와 ndk-build라는 이름으로 저장했음.





Program : JAVA JDK가 설치된 디렉토리 안의 bin\javah.exe

Parameters : -classpath $ModuleFileDir$\build\intermediates\classes\debug -v -jni $FileClass$

Working directory : $ProjectFileDir$\app\src\main\jni


파라미터와 워킹 디렉토리가 문제였는데, 여러 블로그 가봤는데 다 다르다 ㅅㅂ..

그래서 다 해봤는데 되는게 위에꺼.



Program : 안드로이드 NDK가 설치된 디렉토리의 ndk-build.cmd

Parameters : NULL

Working directory : $ProjectFileDir$\app\src\main\jni



3. TextView에 ID 등록


위에서 말했듯이 기본적으로 Hello World!를 출력하는데 이걸 바꾸기 위해 Hell World!를 값으로 가지고 있는 TextView에 ID를 등록함.


안드로이드 우측상단에 Android라고 쓰여 있는(기본적으로는) 버튼이 있다. 그거 눌러서 Project로 바꿈.


내 기준으로 MyApplication\app\src\main\res\layout에 activity_main.xml이 있는데 그거 더블클릭하면 위와 같은 화면이 나옴.



거기서 Hello World!를 더블 클릭하면 위와 같은 창이 나오는데 거기서 id를 등록해주면 된다.



소스 코드에서 직접 수정하고 싶다면 코드에서 밑줄 친 코드를 써주면 된다.



그리고 내 기준으로 MyApplication\app\src\main\java에 com.example.~~~.myapplication 아래에 MainActivity.java가 있는데 이걸 수정해준다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.example.~~~.myapplication;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
 
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        TextView view = (TextView) findViewById(R.id.textview);
        NDKTest ndkt = new NDKTest();
 
        view.setText(ndkt.ndkTestMethod("test"));
        //view.setText("test");
    }
}
cs


JNI에 ndkTestMethod()라는 이름의 jstring을 return하는 함수를 만들 계획이다.

그리고 그 return 값을 Hello World! 대신에 출력시키는게 목표.


1
2
3
static{
    System.loadLibrary("testLib");
}
cs

아, 이것도 class 내부에 넣어주자.



이제 JNI를 만들 java 파일(NDKTest.java)을 생성해준다. 생성 위치는 MainActivity와 동일






msg라는 String type의 인자를 넣어줬는데 이유는 msg라는 평문을 받아서 암호화된 문자열을 return 할 것이기 때문.



이제 main 폴더 아래에 jni라는 디렉토리를 생성해준다. javah.exe가 class 기반으로 동작한다니까 이제 빌드를 해주자.


빌드는 build -> rebuild Project를 누르면 된다.



위에서 생성한 java 파일에 오른쪽 버튼을 누르고 위와 같은 경로를 통해 사전에 등록한 javah를 실행하면 jni 폴더 안에 헤더 파일(com_example_~~~_myapplication.h)이 생성된다.


그리고 이제 jni 폴더 안에 만들어진 헤더 파일을 사용할 cpp 파일(NDKTest.cpp)을 생성한다.




아까 만든 헤더 파일을 include 시키고 대충 이렇게 써주고


\app\src의 build.gradle을 아래와 같이 수정.


1
2
3
4
5
6
7
8
9
10
11
12
 
    defaultConfig {
        applicationId "com.example.~~~.myapplication"
        minSdkVersion 19
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
 
        ndk{
            moduleName "testLib"
        }
    }
cs


defaultConfig 부분에 ndk만 추가해주면 된다.



그리고 \gradle\local.properties에


1
ndk.dir=D\:\\Android\\android-ndk-r12b

cs


위처럼 ndk의 경로를 추가


같은 디렉토리의 gradle.properties에


1
android.useDeprecatedNdk=true
cs


추가




다시 jni 폴더로 가서 Android.mk와 Application.mk를 만들어준다.


그리고 Android.mk에는


1
2
3
4
5
6
7
8
9
LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
 
LOCAL_MODULE := testLib
LOCAL_SRC_FILES := NDKTest.cpp
LOCAL_LDLIBS := -llog
 
include $(BUILD_SHARED_LIBRARY)
cs


Application.mk에는


1
APP_ABL := all
cs

을 써준다.



이름만 봐도 딱 뭐인지 유추 가능하니까 별도의 설명은 생략하도록 하겠다.



이제! 마지막으로 NDKTest.cpp 오른쪽 버튼 클릭해서 이번에는 javah 말고 사전에 등록한 build-ndk를 클릭



이제 컴파일 해보면 위처럼 JNI가 잘 됨을 알 수 있다.



근데 안드로이드 스튜디오에서 AVD로 실행하거나 리얼 머신에서 실행만 할꺼면 사실 Android.mk나 Application.mk가 필요 없다.


.mk 파일은 ndk-build를 할 때만 쓰이는거라서.



2부계--

728x90
반응형

댓글