본문 바로가기
Android

인사이드 안드로이드 04 JNI와 NKD

by OKOK 2021. 5. 15.

4.1 안드로이드와 JNI

location manger가 제공하는 자바 API를 호출함. 이 호출은 프레임워크 내부의 GPS 라이브러리를 통해 GPS 디바이스 드라이버에 연결되어 앱에서 현재 위치 정보 값을 전달해주는 구조로 동작함

- 빠른 처리 속도를 요구하는 루틴 작성

- 하드웨어 제어

- 기존 C/C++ 프로그램의 재사용

 

플랫폼별로 로딩되는 C라이브러리가 있음 

윈도우에서는 .dll 리눅스는 .so

UnsatisfiedLinkError 오류가 발생하는 이유는 자바 가상 머신이 네이티브 메서드와 링크될 코드에서 작성한 hellojni.dll 라이브러리에서 찾지 못했기 떄문이다. 자바 가상 머신 : 함수 매핑 테이블 이런 형태로 C함수 원형을 만들어야 자바 가상 머신이 이 함수와 자바 네이티브 메서드를 링크하는 것이 가능함

자바 클래스 native 메서드 선언 -> javah -> javah로부터 생성된 native 메서드 구현을 위한 함수 프로토타입

 

4.2.2 정리

1. 자바 클래스에 네이티브 메서드 선언

2. javah를 이용해 JNI 네이티브 함수 원형이 포함된 헤더 파일을 생성

3. JNI 네이티브 함수 구현

4. C 공유 라이브러리 빌드

5. JNI를 통한 JNI네이티브 함수 호출

 

반대의 경우 c에서 java를 호출

1. 자바 객체 생성

2. 클래스의 정적 멤버 필드에 접근하기

3. 클래스의 정적 메서드 호출하기

4. 자바 객체의 멤버 필드에 접근하기

5. 자바 객체의 메서드 접근하기

 

JNI를 통한 자바 클래스/객체의 멤버 필드에 대한 접근은 아래와 같은 순서로 이뤄짐

1. 접근하려는 멤버 변수가 선언된 자바 클래스의 jclass 값을 구함

2. 멤버 변수에 대한 jfieldID 값을 얻음. static 변수인 경우 GetStaticFieldID()라는 JNI 함수를 이용하고, 일반 객체의 멤버 변수에 대해서는 GetFieldID라는 JNI 함수를 사용함

3. 1,2 단계에서 구한 jcalss와 jfieldID값을 이용해 멤버 필드 값을 얻거나 설정함

 

4.4 C프로그램에서 자바 클래스 실행하기

C/C++ 프로그램에서 기존에 작성한 자바 기반의 라이브러리를 이용하고 싶을 떄

C/C++ 프로그램에서 자바 표준 라이브러리를 사용하고 싶을 때

자바 프로그램과 상호작용이 자주 필요 할 때.

 

app_process는 안드로이드 프레임워크가 부팅될 떄 안드로이드 런타임을 초기화하고 Zygote 프로세스를 실행하는 역할을 하는 프로세스다. 또한 Zygote는 안드로이드 프레임워크의 성능을 향상시키기 위한 특별한 프로세스로서 모든 앱의 프로세스는 Zygote에서 fork됨. 이러한 Zygote 프로세스는 안드로이드 zygoteInit 클래스라는 자바 프로그램으로 구성돼 있음. 따라서 app_process는 안드로이드가 부팅할 때 JNI 호출 API를 이용해서 자신의 프로그램 영역에 달빈 가상 머신을 로드하고, ZygoteInit 클래스의 main()메서드를 호출해서 Zygote를 실행함

 

4.5.1 네이티브 라이브러리 로드 시에 JNI 네이티브 함수 등록

 

4.6 안드로이드 NDK로 개발하기

안드로이드 메인 앱은 여전히 달빅 가상 머신에서 동작하는 자바 프로그램임

윈도 환경에서 리눅스 기반의 라이브러리를 빌드하기 위해 Cygwin을 설치.

댓글