今回はAndroid NDKのサンプルプロジェクト「hello-jni」のプロジェクトファイルの中を覗いて見る。
プロジェクト内のフォルダ/ファイル構造は以下のようになっている。
\samples\hello-jni\ │ AndroidManifest.xml │ default.properties │ ├―jni │ Android.mk │ hello-jni.c │ ├―res │ └―values │ strings.xml │ ├―src │ └―com │ └―example │ └―hellojni │ HelloJni.java │ └―tests (省略:テストプロジェクト用フォルダ)
■AndroidManifest.xml
このファイルはC言語を利用しないJavaのみのプロジェクトのときと変わらないようだ。Eclipse上でAndroidプロジェクトを作成するときに指定する項目が保存されている。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="https://schemas.android.com/apk/res/android" package="com.example.hellojni" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="3" /> <application android:label="@string/app_name" android:debuggable="true"> <activity android:name=".HelloJni" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
■default.properties
このファイルはC言語を利用しないJavaのみのプロジェクトのときと変わらないようだ。Eclipse上でAndroidプロジェクトを作成するときに指定するターゲットAndroidバージョンが保存されている。
# This file is automatically generated by Android Tools. # Do not modify this file -- YOUR CHANGES WILL BE ERASED! # # This file must be checked in Version Control Systems. # # To customize properties used by the Ant build system use, # "build.properties", and override values to adapt the script to your # project structure. # Project target. target=android-8
■Android.mk
このファイルはC言語のソースファイルをビルドするためのmakeファイルになっている。
# Copyright (C) 2009 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello-jni LOCAL_SRC_FILES := hello-jni.c include $(BUILD_SHARED_LIBRARY)
■hello-jni.c
このファイルはC言語のソースファイル本体だ。
Java_com_example_hellojni_HelloJni_stringFromJNI()という関数を1つ定義、その関数中で文字列を返すだけのソースコードとなっている。
/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include <string.h> #include <jni.h> /* This is a trivial JNI example where we use a native method * to return a new VM String. See the corresponding Java source * file located at: * * apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java */ jstring Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz ) { return (*env)->NewStringUTF(env, "Hello from JNI !"); }
■strings.xml
このファイルはC言語を利用しないJavaのみのプロジェクトのときと変わらないようだ。Eclipse上でAndroidプロジェクトを作成するときに指定するアプリケーション名が保存されている。
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">HelloJni</string> </resources>
■HelloJni.java
このファイルはJavaのソースファイル本体だ。
「System.loadLibrary("hello-jni");」によりC言語側のライブラリを取り込み、
「public native String stringFromJNI();」によりC言語側の関数をJavaで利用できるように定義、
「tv.setText( stringFromJNI() );」で実際にC言語側の関数を呼び出している。
/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.hellojni; import android.app.Activity; import android.widget.TextView; import android.os.Bundle; public class HelloJni extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /* Create a TextView and set its content. * the text is retrieved by calling a native * function. */ TextView tv = new TextView(this); tv.setText( stringFromJNI() ); setContentView(tv); } /* A native method that is implemented by the * 'hello-jni' native library, which is packaged * with this application. */ public native String stringFromJNI(); /* This is another native method declaration that is *not* * implemented by 'hello-jni'. This is simply to show that * you can declare as many native methods in your Java code * as you want, their implementation is searched in the * currently loaded native libraries only the first time * you call them. * * Trying to call this function will result in a * java.lang.UnsatisfiedLinkError exception ! */ public native String unimplementedStringFromJNI(); /* this is used to load the 'hello-jni' library on application * startup. The library has already been unpacked into * /data/data/com.example.HelloJni/lib/libhello-jni.so at * installation time by the package manager. */ static { System.loadLibrary("hello-jni"); } }