Android自助餐之Jni(五)進階

Android自助餐之Jni(五)進階

Android自助餐專欄

Android自助餐之Jni(一)最簡單的運行

Android自助餐之Jni(二)靜態導入so文件

Android自助餐之Jni(三)動態導入so文件

Android自助餐之Jni(四)在線導入so文件

Android自助餐之Jni(五)進階

Android自助餐之Jni(六)NDK入門

C2C++(待完善)

函數聲明

  • Java類:package.name.ClassName.methodName();Java方法:public native String methodName(String value)
  • C:JNIEXPORT jstring JNICALL Java_package_name_ClassName_methodName(JNIEnv *env,jobject obj,jstring value)
  • C++

    //聲明
    extern "C"{
    jstring Java_package_name_ClassName_methodName(JNIEnv *env,jobject obj,jstring value);
    }
    //定義:
    jstring Java_package_name_ClassName_methodName(JNIEnv *env,jobject obj,jstring value){...}

方法調用

  1. GetStringUTFChars
    • C:char * str = (*env)->GetStringUTFChars(env,value,NULL);
    • C++:const char * str = env->GetStringUTFChars(value,NULL);
  2. NewStringUTF
    • C:(*env)->NewStringUTF(env, str);
    • C++:env->NewStringUTF(str);
  3. sprintf
    • C:使用前只需定義第一個參數char * str;
    • C++:使用前需定義第一個參數併爲其分配空間char * str = (char*)malloc(sizeof("size you need"))

使用androidLog

  1. 配置build.gradle

    android {
    //...
    defaultConfig {
    //...
    ndk{
    //...
    ldLibs "log", "z", "m"
    }
    }
    }
  2. include
    在用到log的C/C++中#include <android/log.h>
  3. 調用log
    __android_log_write(ANDROID_LOG_ERROR, "tag","message");

模塊化

當jni文件夾下文件過多不好管理時,可以再jni下新建子文件夾來將文件分模塊管理,引用時寫上子文件名即可。例文件jni/file.h移到jni/file/file.h,對應的include "file.h"改爲include "file/file.h"

類型轉換

  1. java中的String
    在C/C++中用jstring接收,用char*操作,jstring與char*的轉換見上述(C2C++)
  2. java中的int
    在C++中用int接收。

操作bitmap

  1. java代碼

    public native void fun(Bitmap bmp);
  2. C++頭文件
    #include <android/bitmap.h>
  3. C++代碼

    void Java_package_name_ClassName_fun(JNIEnv *env,jobject obj,jobject bmp){
    AndroidBitmapInfo bmpInfo={0};
    if(AndroidBitmap_getInfo(env,bmp,&bmpInfo)<0){return;}
    unsigned char * dataFromBmp=NULL;//此指針即指向bitmap數據的指針
    if(AndroidBitmap_lockPixels(env,bmp,(void **)&dataFromBmp)){return;}//獲取並鎖定bitmap在內存的地址
    //do something with dataFromBmp
    AndroidBitmap_unlockPixels(env,bmp);//操作結束後需要解鎖改地址
    }
  4. 配置build.gradle

    android {
    //...
    defaultConfig {
    //...
    ndk{
    //...
    ldLibs "jnigraphics"
    }
    }
    }
  5. 配置Android.mk
    LOCAL_LDLIBS := -ljnigraphics
  6. clean project

其他

  1. 使用標準庫STL
    • 在jni下新建文件Application.mk並寫入APP_STL := stlport_static
    • 在build.gradle中配置

      android {
      //...
      defaultConfig {
      //...
      ndk{
      //...
      stl "stlport_static"
      }
      }
      }
  2. 開啓異常控制(可以在cpp中throw)

    android {
      //...
      defaultConfig {
          //...
          ndk{
             //...
             cFlags = "-fexceptions"
          }
      }
    }
  3. error: undefined reference to xxx
    一般該錯誤會在cpp中報出,找到對應的h文件,做如下修改

    
    #ifndef _A_H   
    
    
    #define _A_H  
    
    
    
    #ifdef __cplusplus
    
    extern "C"{
    
    #endif
    
    
    ...(文件原有代碼)
    
    
    #ifdef __cplusplus
    
    }
    
    #endif
    
    
    
    #endif  // endof _A_H
    
  4. const char *unsignde char *

    //const cahr * str=...;
    unsigned char * data=(unsigned char *)(const_cast<char*>(str));
發佈了68 篇原創文章 · 獲贊 49 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章