Android NDKでネイティブ開発。
をしようとして割と手こずってるYAGです。
どうしても、画像処理とか、信号処理的な何かを入れようとすると、AndoridのJavaからだと何か遅いんですよね…。Android 2.Xになって、JITコンパイラがちゃんと作動する様なんで、それを通していればそこそこ早くなるらしいですが、カメラ→画像処理→出力みたいな事をやろうとすると途端にめんどっちくなる様です。ぁぁ…。Javaの馬鹿…orz<Javaは信号処理系に弱いと昔から思ってる訳ですけど…
という事で、Nativeです。C++です。と言っても、ANSI Cガリガリでは書けないので、JNIのC(サブセット)です。自分あんまりJNI使ったこと無いんですよね…(汗
Android NDKは今回は最新版のr5を使用。
http://developer.android.com/sdk/ndk/index.html
インストールやサンプルソースの動かし方はこちらのブログを参考に(thx!)
http://techbooster.jpn.org/environment/824/
もろもろ上手く行くと、10倍速位になるらしい。
http://labs.techfirm.co.jp/android/iguchi/1782
凄いワクテカ。
さて、いざ組み込んでみよう…とすると、途端に分からないことがたくさん。特にBitmap周りをどう渡すんだ?という事に。一応、サンプルプログラムのBitmapPlasmaというのがあったので、それを参考にしてみるも、どこでデータの受け渡しをしてるのかさっぱり(汗(一応、*void pixelを通して、データ弄りやってるようなんですけどね…returnはどっから…?というのが…)
まぁ、いきなり大技を狙うより、小技を狙って行きましょうということで、試しに『本当に自分でNative実装含むプロジェクトを作って動くのかTrial』をやってみることに。
JniTest.java
package com.yagu1.JniTest; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Bitmap; import android.graphics.Paint; import android.os.Bundle; import android.view.View; public class JniTest extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new JniView(this)); } /* load our native library */ static { System.loadLibrary("jni-view"); } } class JniView extends View{ private long testcalc; private long mStartTime; /* implementend by libplasma.so */ private static native long timeval(long input, long time_ms); public JniView(Context context) { super(context); // TODO 自動生成されたコンストラクター・スタブ mStartTime = System.currentTimeMillis(); } @Override protected void onDraw(Canvas canvas) { Paint jniPaint = new Paint(); jniPaint.setStyle(Paint.Style.FILL); jniPaint.setARGB(255, 255, 255, 100); testcalc = timeval(testcalc, System.currentTimeMillis() - mStartTime); canvas.drawText(String.valueOf(testcalc), 50, 50, jniPaint); invalidate(); } }
jni-view.c
#include <string.h> #include <jni.h> #include <math.h> #include <stdio.h> #include <stdlib.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 */ JNIEXPORT jlong JNICALL Java_com_yagu1_JniTest_JniView_timeval( JNIEnv* env, jobject this, jlong input, jlong time_ms) { return time_ms; }
Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := jni-view LOCAL_SRC_FILES := jni-view.c include $(BUILD_SHARED_LIBRARY)
色々と迷走してます(汗<Bitmapとか使いたかったんだけどどうやっていいかわからんし。
一応、何とか動いてるようです。ただ…JNIEXPORTとJNICALLが良く分からん><
自分もJavaあんまり分からんくなってきたなぁ…もう一回勉強しなおしかなぁ。