• Android NDK Sample


    基础样例

    create.png

     
    1)C部分
    1.1)TestJni.h
    /* 
     * TestJni.h 
     * 
     *  Created on: 2011-12-20 
     *      Author: Join 
     */ 
     
    #ifndef TESTJNI_H_ 
    #define TESTJNI_H_ 
     
    #include <jni.h> 
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <android/log.h> 
    #include <android/bitmap.h> 
     
    // 测试回调Java 
    #include "CallJava.h" 
     
    #define LOG_TAG "JNI_DEBUG" 
    #define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) 
    #define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) 
     
    // JNI调用函数必须要用C编译器编译 
    // C++不加extern "C",调用会有异常 
    #ifdef __cplusplus 
    extern "C" { 
    #endif 
     
    /* 
     * 说明: 
     * 1、JNIEXPORT、JNICALL:jni的宏,在android的jni中不必须 
     * 2、jstring:返回值类型(对应java的jni基本类型) 
     * 3、C方法名:Java_pacakege_class_method 
     * 4、JNIEnv*、jobject:jni必要参数(分别表示jni环境、java对象) 
     */ 
    // 样例1:获取字符串 
    JNIEXPORT jstring JNICALL Java_org_join_ndk_jni_TestJni_getStr(JNIEnv*, 
            jobject); 
    // 样例2:C回调Java静态及非静态方法 
    JNIEXPORT jstring JNICALL Java_org_join_ndk_jni_TestJni_callJava(JNIEnv*, 
            jobject, int, int, int, int); 
    // 样例3:灰度化图像(Bitmap作为参数)(注:android-8才提供Bitmap.h) 
    JNIEXPORT void JNICALL Java_org_join_ndk_jni_TestJni_convertToGray(JNIEnv*, 
            jobject, jobject); 
     
    // 样例4:缺少JNIEXPORT、JNICALL测试 
    jintArray Java_org_join_ndk_jni_TestJni_getIntArray(JNIEnv*, jobject); 
     
    // 样例5:C方法不按规则命名尝试 
    jint getInt(JNIEnv*, jobject); 
     
    #ifdef __cplusplus 
    } 
    #endif 
     
    // C++调用C 
    //extern "C" { 
    //#include "ImageUtil.h" 
    //} 
     
    //标准头文件为何有如下结构? 
    //#ifdef __cplusplus 
    //extern "C" { 
    //#endif 
    //... 
    //#ifdef __cplusplus 
    //} 
    //#endif 
     
    #endif /* TESTJNI_H_ */

    1.2)TestJni.cpp

    /* 
     * TestJni.cpp 
     * 
     *  Created on: 2011-12-20 
     *      Author: Join 
     */ 
     
    #include "TestJni.h" 
     
    // 样例1:获取字符串 
    JNIEXPORT jstring JNICALL Java_org_join_ndk_jni_TestJni_getStr(JNIEnv *env, 
            jobject obj) { 
        return env->NewStringUTF("I'm from C!"); 
    } 
     
    int min(int x, int y) { 
        return (x <= y) ? x : y; 
    } 
     
    // 样例2:C回调Java静态及非静态方法 
    JNIEXPORT jstring JNICALL Java_org_join_ndk_jni_TestJni_callJava(JNIEnv *env, 
            jobject obj, int add_x, int add_y, int sub_x, int sub_y) { 
        char str[128]; // 字符数组 
        int result_add = add(env, add_x, add_y); // 回调Java静态方法求和 
        LOGE("==[%d+%d=%d]==", add_x, add_y, result_add); 
        int result_sub = sub(env, sub_x, sub_y); // 回调Java非静态方法求差 
        LOGE("==[%d-%d=%d]==", sub_x, sub_y, result_sub); 
        // 将比较得的整数转成字符串 
        sprintf(str, "Hello, I'm Join! min=%d", min(result_add, result_sub)); 
        return env->NewStringUTF(str); 
    } 
     
    typedef struct { 
        uint8_t red; 
        uint8_t green; 
        uint8_t blue; 
        uint8_t alpha; 
    } argb; 
     
    // 样例3:灰度化图像(Bitmap作为参数)(注:android-8才提供Bitmap.h) 
    /** 
     * bitmap:ARGB_8888,32位ARGB位图 
     */ 
    JNIEXPORT void JNICALL Java_org_join_ndk_jni_TestJni_convertToGray(JNIEnv * env, 
            jobject obj, jobject bitmap) { 
        AndroidBitmapInfo info; 
        void* pixels; 
        int ret; 
     
        LOGI("convertToGray"); 
        if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) { 
            LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret); 
            return; 
        } 
     
        LOGI( 
                "color image :: width is %d; height is %d; stride is %d; format is %d;flags is %d", info.width, info.height, info.stride, info.format, info.flags); 
        if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) { 
            LOGE("Bitmap format is not RGBA_8888 !"); 
            return; 
        } 
     
        if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) { 
            LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); 
        } 
     
        // modify pixels with image processing algorithm 
     
        int x, y; 
        uint8_t gray; 
        for (y = 0; y < info.height; y++) { 
            argb * line = (argb *) pixels; 
            for (x = 0; x < info.width; x++) { 
                gray = 0.3 * line[x].red + 0.59 * line[x].green 
                        + 0.11 * line[x].blue; 
                line[x].red = line[x].green = line[x].blue = gray; 
                // line[x].alpha = 0xff; // 完全不透明 
            } 
     
            pixels = (char *) pixels + info.stride; 
        } 
     
        LOGI("unlocking pixels"); 
        AndroidBitmap_unlockPixels(env, bitmap); 
     
    } 
     
    // 样例4:缺少JNIEXPORT、JNICALL测试 
    jintArray Java_org_join_ndk_jni_TestJni_getIntArray(JNIEnv *env, jobject obj) { 
        int array[] = { 12, 34 }; // 新建一个int[] 
        jintArray result = env->NewIntArray(2); // 新建一个jintArray 
        env->SetIntArrayRegion(result, 0, 2, array); // 将int[]存入result 
        return result; 
    } 
     
    // 样例5:C方法不按规则命名尝试 
    jint getInt(JNIEnv *env, jobject obj) { 
        return 256; 
    } 

    1.3)回调相关

             参照Java JNI简单实现一文,讲了些jni注意点的吧?
     
    2)Java部分
    2.1)TestJni
    public class TestJni { 
     
        /** TAG标识 */ 
        private static final String TAG = "TestJni"; 
     
        /** 
         * 载入动态库 
         */ 
        static { 
            System.loadLibrary("TestJni"); 
        } 
     
        /** 样例1:获取字符串 */ 
        public static native String getStr(); 
     
        /** C回调Java方法(静态) */ 
        public static int add(int x, int y) { 
            Log.e(TAG, "==Java静态add方法=="); 
            return x + y; 
        } 
     
        /** C回调Java方法(非静态) */ 
        public int sub(int x, int y) { 
            Log.e(TAG, "==Java非静态sub方法=="); 
            return x - y; 
        } 
     
        /** 样例2:C回调Java静态及非静态方法 */ 
        public static native String callJava(int add_x, int add_y, int sub_x, 
                int sub_y); 
     
        /** 样例3:灰度化图像(Bitmap作为参数)(注:android-8才提供Bitmap.h) */ 
        public static native void convertToGray(Bitmap bitmap); 
     
        /** 样例4:缺少JNIEXPORT、JNICALL测试 */ 
        public static native int[] getIntArray(); 
     
        /** 样例5:C方法不按规则命名尝试 */ 
        public static native int getInt(); 
     
    } 

    2.2)AndroidNDKActivity

    public class AndroidNDKActivity extends Activity implements 
            View.OnClickListener { 
     
        /** 标签 */ 
        private TextView text; 
     
        /** 按钮 */ 
        private Button btn1, btn2, btn3, btn4, btn5; 
     
        /** 图像 */ 
        private ImageView imageView; 
     
        @Override 
        public void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.main); 
     
            /* 初始化话各组件 */ 
            text = (TextView) findViewById(R.id.text); 
            btn1 = (Button) findViewById(R.id.btn1); 
            btn1.setOnClickListener(this); 
            btn2 = (Button) findViewById(R.id.btn2); 
            btn2.setOnClickListener(this); 
            btn3 = (Button) findViewById(R.id.btn3); 
            btn3.setOnClickListener(this); 
            btn4 = (Button) findViewById(R.id.btn4); 
            btn4.setOnClickListener(this); 
            btn5 = (Button) findViewById(R.id.btn5); 
            btn5.setOnClickListener(this); 
            imageView = (ImageView) findViewById(R.id.imageView); 
        } 
     
        @Override 
        public void onClick(View v) { 
            switch (v.getId()) { 
            case R.id.btn1: 
                // 样例1:获取字符串 
                text.setText(TestJni.getStr()); 
                break; 
            case R.id.btn2: 
                // 样例2:C回调Java静态及非静态方法 
                text.setText(TestJni.callJava(2, 5, 8, 3)); 
                break; 
            case R.id.btn3: 
                // 获得Bitmap资源(32位) 
                // BitmapFactory.Options options = new BitmapFactory.Options(); 
                // options.inPreferredConfig = Bitmap.Config.ARGB_8888; 
                // Bitmap bitmap = BitmapFactory.decodeResource(getResources(), 
                // R.drawable.ic_launcher, options); 
                Bitmap bitmap = BitmapFactory.decodeResource(getResources(), 
                        R.drawable.ic_launcher); 
                // 样例3:灰度化图像(Bitmap作为参数) 
                TestJni.convertToGray(bitmap); 
                imageView.setImageBitmap(bitmap); 
                break; 
            case R.id.btn4: 
                // 样例4:缺少JNIEXPORT、JNICALL测试 
                int[] array = TestJni.getIntArray(); 
                int len = array.length; 
                StringBuffer sb = new StringBuffer(); 
                for (int i = 0; i < len - 1; i++) { 
                    sb.append(array[i]); 
                    sb.append(","); 
                } 
                sb.append(array[len - 1]); 
                text.setText(sb.toString()); 
                break; 
            case R.id.btn5: 
                // 样例5:C方法不按规则命名尝试 
                try { 
                    int value = TestJni.getInt(); 
                    text.setText(String.valueOf(value)); 
                } catch (UnsatisfiedLinkError e) { 
                    text.setText("UnsatisfiedLinkError!"); 
                    e.printStackTrace(); 
                } 
                break; 
            } 
        } 
    } 
    三、后记
             整理的基础样例工程,嘿嘿!
     
             注意:
             1)需要2.2系统才可,用了Bitmap.h。
             2)样例5(不按命名规则的那个),用jni对方法进行注册,不按要求写方法名也是可以的。
             3)灰度化是用的标准公式:Gray = R*0.299 + G*0.587 + B*0.114(考虑效率的话,有移位公式)
             4)在android-ndk-r6\platforms\android-8\arch-arm\usr\lib目录下是NDK提供的可调用库。(有OpenGL ES^^)
     
  • 相关阅读:
    mysql 5.7.28 中GROUP BY报错问题 SELECT list is not in GROUP BY clause and contains no
    mysql 的root 用户无法授权,navicat 远程授权提示1044解决方案
    Java equals(),== 和 hashcode()
    一键批处理图片的脚本(将指定目录中的图片处理成要求的分辨率)
    Anaconda环境下GPT2-Chinese的基本使用记录
    Ubuntu WSL 下编译并使用OpenJDK12
    SSM项目下Druid连接池的配置及数据源监控的使用
    《MySql必知必会》笔记整理
    Java面试题整理
    SpringBoot 访问树莓派上的MySql
  • 原文地址:https://www.cnblogs.com/qiengo/p/2599826.html
Copyright © 2020-2023  润新知