Long useless play jni ndk library compiled so, in order to prevent the hand gifted class with a Gaussian blur algorithm needs to be implemented recently practiced hand. Of course, this algorithm is not I realized that I just put this algorithm C code is compiled into a library so because C higher efficiency than java, as the algorithm is very suitable for eating CPU made SO file.
NDK and JNI not described here, and I would say the focus is compiled from a SO library to use this process.
The picture above you can see clear process C / C ++ code to generate the SO library and java layer code calls by KJNI environment.
I compiled with android studio, because SO is a java library and library files and load layer affirms method requires a corresponding interface so we can create a library module directly dependent on the engineering inside, began to explain complete the following steps:
(1) Create a new dependent libraries needed to fill the package name
(2) Configuration build environment
- Local.properties find the file in the library project relies add ndk tool position.
ndk.dir=/home/zhuxingchong/Android/Sdk/ndk-bundle
ndk position file-> project setting can be found below
- For compatibility with earlier versions ndk add file dependencies gradle.properties
android.useDepreCateNdk=true
Add file dependencies build.gradle ndk compiled modules and so files compiled file mk
apply plugin: 'com.android.library'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 23
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk{
moduleName "jni_blur"//生成so文件名
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild{
ndkBuild{
path "src/main/java/jni/Android.mk"//mk文件路径
}
}
}
(3) java file stated function
(4) generating a .h file
javah -d jni com.data.mylibrary.StackNative command generated .h files into the terminal mylibrary / src / main / java directory performed
After the completion of the command execution jni directory will be generated and the generated java directory under the directory
DETAILED .h file code is as follows
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_data_mylibrary_StackNative */
#ifndef _Included_com_data_mylibrary_StackNative
#define _Included_com_data_mylibrary_StackNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_data_mylibrary_StackNative
* Method: blurPixels
* Signature: ([IIII)V
*/
JNIEXPORT void JNICALL Java_com_data_mylibrary_StackNative_blurPixels
(JNIEnv *, jclass, jintArray, jint, jint, jint);
/*
* Class: com_data_mylibrary_StackNative
* Method: blurBitmap
* Signature: (Ljava/lang/Object;I)V
*/
JNIEXPORT void JNICALL Java_com_data_mylibrary_StackNative_blurBitmap
(JNIEnv *, jclass, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
(5) prepare specific logic .c or cpp file, and the file name can be changed .c suffix .h file as cpp or can be, because it is the picture a Gaussian blur processing code do more.
#include <android/log.h>
#include <android/bitmap.h>
#include "stackblur.h"
#define TAG "com_data_mylibrary_StackNative"
#define LOG_D(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__)
JNIEXPORT void JNICALL
Java_com_data_mylibrary_StackNative_blurPixels
(JNIEnv
*env,
jclass obj, jintArray
arrIn,
jint w, jint
h,
jint r
) {
jint *pixels;
// cpp:
// pix = (env)->GetIntArrayElements(arrIn, 0);
pixels = (*env)->GetIntArrayElements(env, arrIn, 0);
if (pixels == NULL) {
LOG_D("Input pixels isn't null.");
return;
}
// Start
pixels = blur_ARGB_8888(pixels, w, h, r);
// End
(*env)->ReleaseIntArrayElements(env, arrIn, pixels, 0);
}
JNIEXPORT void JNICALL
Java_com_data_mylibrary_StackNative_blurBitmap
(JNIEnv
*env,
jclass obj, jobject
bitmapIn,
jint r
) {
AndroidBitmapInfo infoIn;
void *pixels;
// Get image info
if (AndroidBitmap_getInfo(env, bitmapIn, &infoIn) != ANDROID_BITMAP_RESULT_SUCCESS) {
LOG_D("AndroidBitmap_getInfo failed!");
return;
}
// Check image
if (infoIn.format != ANDROID_BITMAP_FORMAT_RGBA_8888 &&
infoIn.format != ANDROID_BITMAP_FORMAT_RGB_565) {
LOG_D("Only support ANDROID_BITMAP_FORMAT_RGBA_8888 and ANDROID_BITMAP_FORMAT_RGB_565");
return;
}
// Lock all images
if (AndroidBitmap_lockPixels(env, bitmapIn, &pixels) != ANDROID_BITMAP_RESULT_SUCCESS) {
LOG_D("AndroidBitmap_lockPixels failed!");
return;
}
// height width
int h = infoIn.height;
int w = infoIn.width;
// Start
if (infoIn.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
pixels = blur_ARGB_8888((int *) pixels, w, h, r);
} else if (infoIn.format == ANDROID_BITMAP_FORMAT_RGB_565) {
pixels = blur_RGB_565((short *) pixels, w, h, r);
}
// End
// Unlocks everything
AndroidBitmap_unlockPixels(env, bitmapIn);
}
(6) the preparation of documents mk
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := jni_blur //生成so文件名
LOCAL_SRC_FILES := stackblur.c com_data_mylibrary_StackNative.c load.c //所有需要编译的c/cpp文件
LOCAL_LDLIBS := -lm -llog -ljnigraphics
include $(BUILD_SHARED_LIBRARY)
Aplication.mk
APP_ABI := all
APP_PLATFORM:= android-23
APP_OPTIM := release
(7) compiled so aar file and package file
Click on android studio right side gradle-> mylibrary-> build-> build
Generate the appropriate library file location
(8) the response so aar file and copy the file to your project libs project
(9) arranged last in the dependent correlation which can be used build.gradle
note:
Generated header files when executed javah -d jni com.data.mylibrary.StackNative error
Error: Unable to determine Bitmap signature
public static native void blurBitmap(Bitmap bitmap, int r);改为
public static native void blurBitmap(Object bitmap, int r);
Last Source: Android-Jni_demo