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){...}
方法調用
- GetStringUTFChars
- C:
char * str = (*env)->GetStringUTFChars(env,value,NULL);
- C++:
const char * str = env->GetStringUTFChars(value,NULL);
- C:
- NewStringUTF
- C:
(*env)->NewStringUTF(env, str);
- C++:
env->NewStringUTF(str);
- C:
- sprintf
- C:使用前只需定義第一個參數
char * str;
- C++:使用前需定義第一個參數併爲其分配空間
char * str = (char*)malloc(sizeof("size you need"))
- C:使用前只需定義第一個參數
使用androidLog
- 配置
build.gradle
android {
//...
defaultConfig {
//...
ndk{
//...
ldLibs "log", "z", "m"
}
}
}
- include
在用到log的C/C++中#include <android/log.h>
- 調用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"
。
類型轉換
- java中的String
在C/C++中用jstring接收,用char*操作,jstring與char*的轉換見上述(C2C++) - java中的int
在C++中用int接收。
操作bitmap
- java代碼
public native void fun(Bitmap bmp);
- C++頭文件
#include <android/bitmap.h>
- 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);//操作結束後需要解鎖改地址
}
- 配置build.gradle
android {
//...
defaultConfig {
//...
ndk{
//...
ldLibs "jnigraphics"
}
}
}
- 配置Android.mk
LOCAL_LDLIBS := -ljnigraphics
- clean project
其他
- 使用標準庫STL
- 在jni下新建文件
Application.mk
並寫入APP_STL := stlport_static
- 在build.gradle中配置
android {
//...
defaultConfig {
//...
ndk{
//...
stl "stlport_static"
}
}
}
- 在jni下新建文件
開啓異常控制(可以在cpp中throw)
android { //... defaultConfig { //... ndk{ //... cFlags = "-fexceptions" } } }
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
const char *
轉unsignde char *
//const cahr * str=...; unsigned char * data=(unsigned char *)(const_cast<char*>(str));