Android JNI 개발 입문 중 하나


JNI 는 안 드 로 이 드 시스템 에서 광범 위 하 게 응용 되 고 있다.Android 시스템 의 바 텀 은 모두 C/C++로 이 루어 졌 고 상부 에서 제공 하 는 API 는 모두 자바 이 며 자바 는 JNI 를 통 해 바 텀 을 호출 하여 이 루어 졌 다.예 를 들 어 Android API 멀티미디어 인터페이스 MediaPlayer 류 는 사실 바 텀 에서 JNI 를 통 해 libmedia 라 이브 러 리 를 호출 합 니 다.JNI 의 존재 로 인해 우 리 는 이미 C/C++가 존재 하 는 라 이브 러 리 를 많이 재 활용 하여 중복 개발 의 번 거 로 움 을 줄 일 수 있 고 많은 오픈 소스 라 이브 러 리(Android 라 이브 러 리 에 많은 오픈 소스 라 이브 러 리,예 를 들 어 libjpeg,libpng 등)를 이용 할 수 있 으 며 우리 가 개발 한 프로그램 을 더욱 효율 적 으로(C/C+코드 가 하드웨어 의 가장 좋 은 성능 을 발휘 하도록 합 니 다).표준 JNI 에 대해 잘 모 르 시 면 제 블 로그'를 참고 하 세 요.
Linux 에서 JNI 구현
이 글 은 표준 JNI 로 리 눅 스 시스템 에서 Helloworld 프로그램 을 실현 하 는 방법 을 소개 하 며 JNI 에 대한 초보적인 인식 을 갖 게 한다.본 고 는 안 드 로 이 드 아래 에서 JNI 개발 프로그램 을 어떻게 사용 하 는 지 간단하게 소개 하고 전형 적 인 Helloworld 응용 프로그램 을 개발 하 는 방법 을 소개 한다.
교차 컴 파일 환경
    먼저 교차 컴 파일 환경 을 구축 해 야 합 니 다.자바 층 의 응용 프로그램 은 하드웨어 와 무관 하기 때문에 JDK 컴 파일 하면 됩 니 다.그러나 Native C/C+코드 는 하드웨어 와 관련 된 것 이 므 로 교차 컴 파일 러 로 특정 하드웨어 실행 가능 코드 로 컴 파일 해 야 합 니 다.하드웨어 플랫폼 에 따라 교차 컴 파일 환경 을 구축 하 십시오.제 MIPS 플랫폼 은 물론 MIPS 의 교차 컴 파일 러 를 선택 하 였 습 니 다.만약 에 Arm 이 라면 자신의 교차 컴 파일 러 를 설정 하 십시오.
    우 리 는 먼저 Native C 의 helloworld 프로그램 을 컴 파일 합 니 다.안 드 로 이 드 에 프로그램 을 추가 하 는 방법 을 배 울 수 있 습 니 다.또한 우리 의 교차 컴 파일 환경 이 정확 한 지 검증 할 수 있 습 니 다.을 참고 할 수 있 습 니 다.만약 이 단계 에 문제 가 없다 면 당신 의 교차 컴 파일 환경 이 문제 가 없다 는 것 을 설명 하고 계속 아래로 진행 할 수 있 습 니 다.
자바 가 만 든 안 드 로 이 드 응용 프로그램
    우선 자바 로 helloworld 응용 프로그램(APK)을 작성 합 니 다.이 코드 는 HelloWorld activity 를 간단하게 만 듭 니 다.코드 는 다음 과 같 습 니 다:
package com.simon;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class HelloWorld extends Activity {
    private static final String TAG = "HelloWorld";
	static {
		System.loadLibrary("helloworld");
	}

	private native String printJNI();

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Log.d(TAG, "Activity call JNI: " + printJNI());
    }
}

     이 Hello World Activity 는 매우 간단 합 니 다.JNI 인터페이스 printJNI()를 호출 하여 안 드 로 이 드 로 거 에 정 보 를 인쇄 할 뿐 입 니 다.우리 가 주목 해 야 할 것 은 printJNI()의 성명 입 니 다.native 키 워드 는 그 가 native 코드 로 이 루어 진 함수 이 고 JNI 로 Native 코드 를 호출 해 야 한 다 는 것 을 설명 합 니 다.또한 static 코드 세그먼트 에 주의 하 십시오.이 코드 는 Hello World 가 처음 불 러 올 때 libhelloworld.so 를 불 러 오 는 것 을 의미 합 니 다.그래서 loadLibrary 의 인 자 는 libhelloworld.so 가 아니 라 helloworld 입 니 다.잘못 쓰 면 라 이브 러 리 를 불 러 오 는 데 실 패 했 습 니 다.이상 을 받 을 수 있 습 니 다.)
C 언어 구현 helloworld 공유 라 이브 러 리
     다음은 네 이 티 브 코드 부분 을 완성 해 야 합 니 다.여기 서 강조해 야 합 니 다.안 드 로 이 드 JNI 실현 에서 C/C++에 서로 다른 API 두 세트 를 제공 합 니 다.호출 할 때 주의해 야 합 니 다.그렇지 않 으 면 libc 라 이브 러 리 의 붕괴 정 보 를 받 을 수 있 습 니 다.'붕괴'할 수도 있 습 니 다.하하!다음은 네 이 티 브 C 를 실현 하여 helloworld 라 이브 러 리 를 실현 합 니 다.
     자바 표준 JNI 에 익숙 하 다 면 자바 도 구 를 알 고 있 을 것 입 니 다.자바 소스 프로그램 에 따라 네 이 티 브 코드 의 헤더 파일 을 생 성 할 수 있 습 니 다.Eclipse 에서 apk 를 개발 하고 있다 면 터미널 을 열 고 bin 디 렉 터 리 에 들 어가 서 실행 할 수 있 습 니 다.
javah com.simon.HelloWorld

당신 은'헤더 파일 come'을 얻 을 수 있 습 니 다.simon_Helloworld.h,printJNI 인터페이스 가 있 는 C/C++성명 을 포함 합 니 다.이 성명 은 틀림없이 정확 할 것 이다.만약 당신 이 printJNI 인터페이스 성명 을 잘못 썼 다 면 HelloWorld 는 printJNI 인 터 페 이 스 를 찾 지 못 하고 붕 괴 될 것 이다.
     우리 com 만 들 기simon_Helloworld.c 파일 을 입력 하고 이 파일 에 입력 하 십시오:
#include <jni.h>
#define LOG_TAG "HelloWorld"
#include <utils/Log.h>

/* Native interface, it will be call in java code */
JNIEXPORT jstring JNICALL Java_com_simon_HelloWorld_printJNI(JNIEnv *env, jobject obj)
{
    LOGI("Hello World From libhelloworld.so!");

    return (*env)->NewStringUTF(env, "Hello World!");
}

/* This function will be call when the library first be load.
 * You can do some init in the libray. return which version jni it support.
 */
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    void *venv;
    LOGI("JNI_OnLoad!");

    if ((*vm)->GetEnv(vm, (void**)&venv, JNI_VERSION_1_4) != JNI_OK) {
        LOGE("ERROR: GetEnv failed");
        return -1;
    }

     return JNI_VERSION_1_4;
}

자바com_simon_HelloWorld_printJNI 함수 의 이름 입 니 다.이 이름 은 JNI 규범 에 맞 는 자바 입 니 다.처음에 뒤에 그의 유형 명(가방 이름과 유형 명 포함,comsimon_Hello World),그리고 인터페이스의 이름 printJNI 입 니 다.이렇게 하면 자바 가상 머 신 은 com.simon.HelloWorld 클래스 에서 printJNI 인 터 페 이 스 를 호출 할 때 이 C 에서 실 현 된 Native 함수 호출 을 자동 으로 찾 을 수 있 습 니 다.너 는 이 이름 이 매우 길 다 는 것 을 알 수 있 을 것 이다.함수 명 으로서 그것 은 좋 은 선택 이 아 닐 수도 있다.JNI API 는 함수 맵 표를 제공 하여 Jave 가상 머 신 에 등록 할 수 있 도록 합 니 다.그러면 자바 가상 머 신 은 함수 맵 표 로 해당 함 수 를 호출 할 수 있 습 니 다.함수 이름 을 통 해 호출 할 함 수 를 찾 지 않 아 도 됩 니 다.이렇게 하면 함수 이름 도 마음대로 정의 할 수 있 습 니 다.(함수 기능 을 가장 잘 표현 할 수 있 는 함수 이름 을 정의 할 수 있 습 니 다)이것 은 helloworld 공유 라 이브 러 리 의 C++구현 에서 보 여 줍 니 다.하지만 안 드 로 이 드 시스템 에 서 는 JNI 표준 함수 명 으로 정의 하 는 것 을 추천 합 니 다.
    JNI_OnLoad 함수 JNI 는 공유 라 이브 러 리 가 처음 불 러 올 때 리 셋 됩 니 다.이 함수 에 서 는 등록 함수 맵,캐 시 변수 등 초기 화 작업 을 할 수 있 습 니 다.마지막 으로 현재 환경 이 지원 하 는 JNI 환경 으로 돌아 갑 니 다.이 예 는 현재 JNI 환경 을 간단하게 되 돌려 주 는 것 입 니 다.
주의 하 세 요.인터넷 에서 JNI 를 안 해도 된다 는 예 가 많아 요.OnLoad,이 루어 지지 않 으 면 printJNI 는 전체 형식의 값 만 되 돌려 주 고 다른 유형의 값 을 되 돌려 주면 무 너 질 수 있다 는 것 을 알 게 되 었 습 니 다.그리고 GetEnv 의 호출 도 필수 입 니 다.그렇지 않 으 면 무 너 집 니 다.그러나 GetEnv 의 반환 값 은 제 가 사용 하지 않 았 습 니 다.이런 부분 들 은 저 를 매우 현혹 시 켰 고 달인 의 해 혹 을 기대 합 니 다.
    다음은 Android.mk 파일 을 작성 하여 만 들 고 입력 하 십시오.
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:=com_simon_Helloworld.c

LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)

LOCAL_MODULE := libhelloworld

LOCAL_SHARED_LIBRARIES := libutils

LOCAL_PRELINK_MODULE := false

include $(BUILD_SHARED_LIBRARY)

     이 안 에는 설명 이 필요 한 라벨 이 몇 개 있다.
1、LOCAL_C_INCLUDES 는 포 함 된 헤더 파일 을 설명 합 니 다.JNI 를 포함 하 는 헤더 파일 이 필요 합 니 다.
2、LOCAL_MODULE 현재 모듈 이름
3、LOCAL_SHARED_LIBRARIES 현재 모듈 은 의존 하 는 공유 라 이브 러 리 가 필요 합 니 다.hellowold 에서 우 리 는 Android 인쇄 시스템 을 logger 로 출력 하기 때문에 libutils 라 이브 러 리 에 의존 해 야 합 니 다.
4、LOCAL_PRELINK_MODULE 은 이 모듈 이 시작 되면 불 러 올 지 여 부 를 가리 키 며,을 참고 할 수 있 습 니 다.우리 Hello World 라 이브 러 리 는 prelink 가 필요 없 기 때문에 false 로 설정 합 니 다.
    이 모듈 을 컴 파일 합 니 다.환경 에 따라 컴 파일 경 로 를 선택 하 십시오.그리고 apk 를 설치 하고 실행 하면 logcat 도 구 를 통 해 해당 하 는 출력 을 볼 수 있 습 니 다.

좋은 웹페이지 즐겨찾기