Scala 㧠Android ã¢ããªéçº(NDK ç·¨)
ä¸æºå
å§ãã« /path/to/hello-world/project/build.scala ã次ã®ããã«ä¿®æ£ããã
// ..snip.. object AndroidBuild extends Build { lazy val main = Project ( "Hello World", file("."), settings = General.fullAndroidSettings ++ AndroidNdk.settings // ããã追å ) // ..snip.. }
次㫠/path/to/hello-world/src/main/jni/ ãä½æããã
$ make -p /path/to/hello-world/src/main/jni/
ã©ããã¼ã¯ã©ã¹ãä½ã
ãã®ã¯è©¦ãã«ãã¡ã¤ã«ã®æ å ±ãåå¾ããã©ãã /path/to/hello-world/src/main/scala/FileStat.scala ãä½æããã
package com.github.cooldaemon.HelloWorld import _root_.java.io.File import _root_.java.util.{Map => JMap} import _root_.scala.collection.JavaConversions._ object extendFileStat { implicit def fileToFileStat(file: File): FileStat = new FileStat(file) } class FileStat(file: File) { System.loadLibrary("file_stat") @native private[this] def getStat(name: String): JMap[String, Long] def stat: Map[String, Long] = mapAsScalaMap(getStat(file.toString)).toMap }
C é¢é£ã®ãã¡ã¤ã«ãç¨æãã
.class ãã¡ã¤ã«ãä½ãããä¸åº¦ã³ã³ãã¤ã«ãããã®å¾ãjavah ã§ã©ããã¯ã©ã¹ãã C ããããã¡ã¤ã«ãä½æããã
$ cd /path/to/hello-world $ sbt > compile > exit $ javah -o ./src/main/jni/file_stat.h -classpath ./target/scala-2.9.1/classes com.github.cooldaemon.HelloWorld.FileStat
sbt çµç±ã§ javah ãå®è¡ããæ¹æ³ã¯è©¦ãã¦ããªãã
Makefile ã¨ã㦠/path/to/hello-world/src/main/jni/Android.mk ãä½æããã
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := file_stat LOCAL_SRC_FILES := file_stat.c #LOCAL_C_INCLUDES += $(SBT_MANAGED_JNI_INCLUDE) include $(BUILD_SHARED_LIBRARY)
æå¾ã«ãã¡ã¤ã«æ¬ä½ /path/to/hello-world/src/main/jni/file_stat.c ãä½æããã
#include <sys/stat.h> #include "file_stat.h" jobject NewLong(JNIEnv* env, jlong value) { jclass longClass = (*env)->FindClass(env, "java/lang/Long"); jmethodID init = (*env)->GetMethodID(env, longClass, "<init>", "(J)V"); jobject longObj = (*env)->NewObject(env, longClass, init, value); (*env)->DeleteLocalRef(env, longClass); return longObj; } JNIEXPORT jobject JNICALL Java_com_github_cooldaemon_HelloWorld_FileStat_getStat (JNIEnv *env, jobject obj, jstring name) { jclass mapClass = (*env)->FindClass(env, "java/util/HashMap"); jmethodID init = (*env)->GetMethodID(env, mapClass, "<init>", "(I)V"); jobject mapObj = (*env)->NewObject(env, mapClass, init, 1); jmethodID put = (*env)->GetMethodID(env, mapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); jboolean iscopy; const char *mfile = (*env)->GetStringUTFChars(env, name, &iscopy); struct stat finfo; lstat(mfile, &finfo); (*env)->CallObjectMethod(env, mapObj, put, (*env)->NewStringUTF(env, "dev"), NewLong(env, finfo.st_dev) ); (*env)->CallObjectMethod(env, mapObj, put, (*env)->NewStringUTF(env, "ino"), NewLong(env, finfo.st_ino) ); (*env)->CallObjectMethod(env, mapObj, put, (*env)->NewStringUTF(env, "mode"), NewLong(env, finfo.st_mode) ); (*env)->CallObjectMethod(env, mapObj, put, (*env)->NewStringUTF(env, "nlink"), NewLong(env, finfo.st_nlink) ); (*env)->CallObjectMethod(env, mapObj, put, (*env)->NewStringUTF(env, "uid"), NewLong(env, finfo.st_uid) ); (*env)->CallObjectMethod(env, mapObj, put, (*env)->NewStringUTF(env, "gid"), NewLong(env, finfo.st_gid) ); (*env)->CallObjectMethod(env, mapObj, put, (*env)->NewStringUTF(env, "rdev"), NewLong(env, finfo.st_rdev) ); (*env)->CallObjectMethod(env, mapObj, put, (*env)->NewStringUTF(env, "size"), NewLong(env, finfo.st_size) );
ã³ã³ãã¤ã«ãã¦ã¿ãã
$ sbt > android:ndk-build
使ç¨ãã
val f = new File(context.getFilesDir, "foo") import extendFileStat._ f.stat foreach {case (k, v) => Log.d(k + ":" + v.toString)}