android jni 程式架構搭建

來源:互聯網
上載者:User

android上 jni開發 應用構建過程基本一致,下面 結合最近 在android 上實現 jni層 繪製  surfaceview 功能 闡述 帶jni的apk構建過程。

apk 目錄結構:

├── AndroidManifest.xml├── Android.mk├── jni│   ├── Android.mk│   ├── logger.cpp│   ├── logger.h│   ├── OnLoad.cpp│   └── SurfaceviewJni.cpp├── libs│   └── armeabi│       └── libsurfaceviewJni.so├── res│   ├── layout│   │   └── hello_activity.xml│   └── values│       └── strings.xml└── src    └── com        └── example            └── android                └── jnisurfaceview                    ├── JavasurfaceView.java                    └── JniSurfaceViewActivity.java

1.  java類中 static 塊 載入動態庫及java層本地方法聲明 :

  static {

System.loadLibrary("surfaceviewJni");

 private native void nativeSetSurface(Surface surface);
   private native void nativeDraw(String path ,int width, int height);

2 .  編寫 jni makefile

   jni/Android.mk

#lib for jnisurfaceviewLOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_LDLIBS := \        -lm -lstdc++ -lgcc -llogLOCAL_SRC_FILES := \OnLoad.cpp \SurfaceviewJni.cpp \                logger.cpp#LOCAL_SHARED_LIBRARIES := libsurfaceviewJniLOCAL_SYSTEM_SHARED_LIBRARIES := libc libstdc++ libutils LOCAL_MODULE := libsurfaceviewJniinclude $(BUILD_SHARED_LIBRARY)

3. 編寫 apk makefile 

LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)# Only compile source java files in this apk.LOCAL_SRC_FILES := $(call all-java-files-under, src)LOCAL_PACKAGE_NAME := JniSurfaceView#LOCAL_JNI_SHARED_LIBRARIES := libsurfaceviewJni#LOCAL_PRELINK_MODULE := falseinclude $(BUILD_PACKAGE)

4. C/C++代碼中綁定java層和本地介面

這裡的關鍵點在 JNI_OnLoad 函數,java層在 load 動態庫時虛擬機器會首先調用動態庫中的JNI_OnLoad,所以 java層介面和本地介面的綁定在JNI_OnLoad 函數中初始化即可,這也是android framework 的做法。

放在一個檔案中:

OnLoad.cpp

/* * Desc: jni code for surfaceview * Author :lidp */ #include <android/log.h>#include <jni.h>#include "logger.h"#define TAG_JNISURFACEVIEW "jni surfaceview test"static JavaVM *jvm = NULL;int register_jnisurfaceview(JNIEnv* env);JNJEnv* getEnv(){JNIEnv* env = NULL;if(jvm->GetEnv(void**)&env, JNI_VERSION_1_4) != JNI_OK) {return NULL;droid_log(LOG_ERROR,"failed in get jvm\n");}return env;}//this function will be called by jvm on load shared libjint JNI_OnLoad(JavaVM *vm,void* reserved){JNIEnv* env = NULL;jint ret = JNI_ERR;droid_log(LOG_DEBUG,"Jni Onload be called\n");jvm = vm;if(jvm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {droid_log(LOG_ERROR,"failed get jvm\n");return ret;}if(register_jnisurfaceview(env) != JNI_OK)return ret;;return JNI_VERSION_1_4;}

5. 實現介面代碼:

SurfaceviewJni.cpp

#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <android/log.h>#include "logger.h"#include <jni.h>struct JavaGule {jobject jsurface;};static struct JavaGule gule;//code pase from framework jnihelp.cppstatic int jniRegisterNativeMethods(JNIEnv* env, const char* className, const JNINativeMethod* gMethods, int numMethods){    jclass clazz;droid_log(LOG_DEBUG, "register native method for class %s\n", className);    clazz = env->FindClass(className);    if (clazz == NULL)        return -1;    if (env->RegisterNatives(clazz, gMethods, numMethods) < 0)        return -1;    return 0;}static void jnisurfaceview_draw(JNIEnv *env, jobject obj, jstring photopath, jint w, jint h){droid_log(LOG_DEBUG, "native draw be called \n");jclass sufaceClass = env->FindClass("android/view/Surface");if(sufaceClass == NULL) {droid_log(LOG_ERROR,"Cant not find android/view/Surface class\n");return;}jfieldID surfaceID = env->GetFieldID(sufaceClass, "mSurface", "I");    if (surfaceID == NULL) {        droid_log(LOG_ERROR,"Can't find Surface.mSurface");        return;    }//sp<Surface> surface = (Surface *)env->GetIntField(gule.jsurface, surfaceID);/*if(surface.isValid()) {} else {droid_log(LOG_ERROR, "cant get surface\n");}*/}static void jnisurfaceview_setSurface(JNIEnv *env, jobject obj, jobject javasurface){droid_log(LOG_DEBUG, "native setSurface be called \n");gule.jsurface = javasurface;}static JNINativeMethod gmethods[] = {{"nativeDraw", "(Ljava/lang/String;II)V", (void *)jnisurfaceview_draw},{"nativeSetSurface", "(Landroid/view/Surface;)V", (void*)jnisurfaceview_setSurface},};int register_jnisurfaceview(JNIEnv* env){return jniRegisterNativeMethods(env,"com/example/android/jnisurfaceview/JavasurfaceView", gmethods, sizeof(gmethods)/sizeof(gmethods[0]));}

6.  ndk_build 編譯 jni目錄,產生動態庫到 libs目錄,

    apk 根目錄 執行 mm 產生apk. 

注意:

這裡本地代碼用到了 ndk提供的log 介面 android/log.h 所以在makefile中要串連log動態庫 用參數

LOCAL_LDLIBS := \        -lm -lstdc++ -lgcc -llog

上面的 c++代碼即包含 java->c++的調用也包含 C++  -> java的反調用。

ok.

 csdn lidp 原創,轉載著名出處,謝謝。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.