android jni介绍

Jni API:https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/jniTOC.html
JNIEnv、jobject和jclass这三种基本类型

操作API都在JNIEnv中,JNIEnv为Java与C/C++通信桥梁
jobject:Java层传递的对象(普通native方法传递)
jclass:Java层对应的Class类(静态native方法传递)

native普通方法与静态方法区别:Jni传递参数是jobject和jclass区别

android studio ndk api自动补齐
安装插件:
Android NDK Support
NDK WorkspaceManager Support

属性,方法,数组例子:
Java层
public class MainActivity extends AppCompatActivity {

private static final String TAG = "MainActivity";
//测试属性
public String strName ="test";

//排序数组
private int[] array = {89,2,4,34,88,100,1};
// Used to load the ‘native-lib‘ library on application startup.
static {
    System.loadLibrary("native-lib");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Example of a call to a native method
    TextView tv = (TextView) findViewById(R.id.sample_text);

    //测试属性操作
    tv.setText(updateStringFromC());
    //测试方法调用
    tv.setText(getJavaMethod());

    //测试数组操作
    this.operateArraySort(array);
    for (int i = 0; i < array.length; i++){
        Log.e(TAG, "onCreate: " + array[i]);
    }

    //异常处理 C++的异常 JAVA是无法try catch的,如果jni层出现了异常,那么Java的代码调用中止
    try {
        exception();
    }catch (Exception e){
        Log.e(TAG, "onCreate: " + e.getMessage());
    }
    Log.e(TAG, "onCreate: " + "end");

}
//测试方法
public String getMethod(int a){
    return "method" + a;
}

/**
 * A native method that is implemented by the ‘native-lib‘ native library,
 * which is packaged with this application.
 */
public native String stringFromJNI();
//从C返回字符串
public native String updateStringFromC();
//调用Java方法
public native String getJavaMethod();
//对array数组进行排序操作
public native void operateArraySort(int[] array);
//异常处理
public native void exception();

}

Jni层:

#include <jni.h>
#include <string>
#include "stdlib.h"

//C C++混编

int compare(const void* lhs, const void* rhs){
    return (*(int*)lhs - *(int*)rhs);
}

//异常处理
extern "C"
JNIEXPORT void JNICALL
Java_com_home_adproj_androidndktest_MainActivity_exception(JNIEnv *env, jobject instance) {
    jclass  _jclass = env->GetObjectClass(instance);
    jfieldID _jfieldID = env->GetFieldID(_jclass,"strName2","Ljava/lang/String;");//strName2不存在有异常
    if(env->ExceptionCheck()){//检测异常
        env->ExceptionClear();//清除异常 不会使Java层崩溃
        //抛异常给Java层
        jclass exceptionClass = env->FindClass("java/lang/IllegalArgumentException");
        env->ThrowNew(exceptionClass,"strName2 不存在");//抛异常到Java层,Java层进行捕获
    }
}

//对Java数组进行操作
extern "C"
JNIEXPORT void JNICALL
Java_com_home_adproj_androidndktest_MainActivity_operateArraySort(JNIEnv *env, jobject instance,
                                                                  jintArray array_) {
    jint *arrays = env->GetIntArrayElements(array_, NULL);
    int _len = env->GetArrayLength(array_);//获取数组长度
    //qsort(void* __base, size_t __nmemb, size_t __size, int (*__comparator)(const void* __lhs, const void* __rhs));
    qsort(arrays,_len, sizeof(int),compare);//数组排序
    env->ReleaseIntArrayElements(array_, arrays, 0);//释放
}

//调用Java层方法
extern "C"
JNIEXPORT jstring JNICALL
Java_com_home_adproj_androidndktest_MainActivity_getJavaMethod(JNIEnv *env, jobject instance) {
    jclass _jclass =env->GetObjectClass(instance);
    //(jclass clazz, const char* name, const char* sig)
    jmethodID _jmethodID = env->GetMethodID(_jclass,"getMethod","(I)Ljava/lang/String;");//(参数类型)Ljava/lang/String返回值类型
    jstring result = (jstring) env->CallObjectMethod(instance, _jmethodID,100);
    char* str = (char *) env->GetStringUTFChars(result, NULL);//string 转char
    return env->NewStringUTF(str);
}

//测试Java属性操作
extern "C"
JNIEXPORT jstring JNICALL
Java_com_home_adproj_androidndktest_MainActivity_updateStringFromC(JNIEnv *env, jobject instance) {
    // TODO
    jclass _jclass = env->GetObjectClass(instance);
    //(jclass clazz, const char* name, const char* sig)
    //name:属性名  sig:属性类型
    jfieldID _jfieldID = env->GetFieldID(_jclass,"strName","Ljava/lang/String;");
    jstring _result = (jstring) env->GetObjectField(instance, _jfieldID);

    //如何转化成java string
    char* str = (char *) env->GetStringUTFChars(_result, NULL);

    char text[20] = "success";
    return env->NewStringUTF(strcat(str,text));
}

extern "C"
JNIEXPORT jstring JNICALL
Java_com_home_adproj_androidndktest_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

lldb:jni调试工具
官网:http://lldb.llvm.org/tutorial.html

原文地址:http://blog.51cto.com/xuguohongai/2156670

时间: 2024-10-03 14:57:39

android jni介绍的相关文章

Android jni aes加解密,实现文件的加解密,具体实现可以自行修改,上面的代码为简单介绍,下面的是JNI端实现文件加解密,可以修改为字符串加解密

#include "aes.h" #include "modes.h" #include "e_os2.h" #include "aes_locl.h" #include "opensslconf.h" AES_KEY aes; //aes cbc模式加解密用到的向量 unsigned char iv[AES_BLOCK_SIZE]; for (i = 0; i < AES_BLOCK_SIZE; i

【转】android JNI

原文网址:http://jinguo.iteye.com/blog/696185 Java Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) 内部运行的 Java 代码能够与用其它编程语言(如 C.C++ 和汇编语言)编写的应用程序和库进行交互操作. 1.从如何载入.so档案谈起 由于Android的应用层的类都是以Java写的,这些Java类编译为Dex型式的Byt

Android jni 编程入门

本文将介绍如何使用eclipse和ndk-build来编写一个基于Android4.4版本的包含有.so动态库的安卓程序. 前提是已经安装和配置好了诸如SDK,NDK等编译环境.下面开始编程! 1 程序逻辑 我们要编写的程序包含两部分:java部分--负责界面和调用JNI native函数:JNI native 部分--负责native函数的具体实现(本文使用C语言). native 函数伪代码如下: ? 1 2 3 4 5 6 7 8 /* funtion: 传入两个整形变量,计算他们之和 r

Ubuntu下编译Android JNI实例全过程

第一步:保证make和gcc可用 在shell中输入make-v,不报错就是对的.(可参考http://wenku.baidu.com/view/d87586c24028915f804dc24a.html.) 在shell中输入gcc-v,不报错就是对的. 第二步:安装NDK 下载NDK后,设置环境变量: 将android-ndk的路劲加到环境变量PATH中:sudogedit /etc/environment 然后再让这个更改的环境变量立即生效:source /etc/environment

Android bluetooth介绍(三): 蓝牙扫描(scan)设备分析

关键词:蓝牙blueZ  A2DP.SINK.sink_connect.sink_disconnect.sink_suspend.sink_resume.sink_is_connected.sink_get_properties.AUDIO.DBUS版本号:基于android4.2之前版本号 bluez内核:linux/linux3.08系统:android/android4.1.3.4作者:xubin341719(欢迎转载.请注明作者.请尊重版权谢谢)欢迎指正错误.共同学习.共同进步!! 參考

八、android jni 之C语言基础

*含义 1.乘法 3*5 2.定义指针变量 int * p://定义了一个名字叫p的变量,能够存放int数据类型的地址 3.指针运算符, //如果p是一个已经定义好的指针变量则*p表示以p的内容为地址的变量 打印数据类型 %d - int %ld – long int %c - char %f - float %lf – double %x – 十六进制输出 int或者long int或者short int %o - 八进制输出 %s – 字符串 3.指针 指针就是地址. 热身小程序 介绍指针

android jni 之C语言基础

*含义 1.乘法 3*5 2.定义指针变量 int * p://定义了一个名字叫p的变量,能够存放int数据类型的地址 3.指针运算符, //如果p是一个已经定义好的指针变量则*p表示以p的内容为地址的变量 打印数据类型 %d - int %ld – long int %c - char %f - float %lf – double %x – 十六进制输出 int或者long int或者short int %o - 八进制输出 %s – 字符串 3.指针 指针就是地址. 热身小程序 介绍指针

超全Android JNI&NDK编程总结

由于网上关于JNI/NDK相关的知识点介绍的比较零散而且不具备参照性,所以写了这篇JNI/NDK学习笔记,便于作为随时查阅的工具类型的文章,本文主要的介绍了在平时项目中常用的命令.JNI数据类型.签名等,便于查阅相关资料.文末相关参考资料比较适合刚接触或者不熟悉Android NDK开发的朋友参阅. 常用命令 javac 编译java源文件生成.class文件 由于JNI对应的头文件由javah工具根据对应的.class文件生成,所以在进行JNI编程之前,写好Java代码后需要先编译,在使用ja

Android jni简便开发流程

<Android jni helloworld>中介绍了开发jni helloworld的步骤,本文将介绍jni简便开发流程 ① 写java代码 native 声明本地方法 ② 添加本地支持 右键单击项目->andorid tools->add native surport 如果发现 finish不能点击,需要给工作空间配置ndk目录的位置 window->preferences->左侧选择android->ndk 把ndk解压的目录指定进来 右键单击项目->