Android NDK 学习之在C中抛出异常
本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件。
在Eclipse中添加配置NDK,路径如下Eclipse->Window->Preferences->Android->NDK ,选择NDK的路径,然后Apply即可。
新建一个名为AndroidJNI_CathcThrow的Android工程,新建一个jni的文件夹,其目录下文件树列表如下:
├── jni
│ ├── Android.mk
│ ├── Application.mk
│ └── catchthrow
│ ├── Android.mk
│ ├── catchthrow_jni.c
│ └── logger.h
jni/Application.mk文件内容如下:
APP_ABI := all
jni/Android.mk,主要用来指定顺序执行所有子文件夹下面的makefile文件,内容如下:
include $(call all-subdir-makefiles)
jni/catchthrow/Android.mk,主要用来指定需要编译出的动态库的名称,以及需要编译的源文件,内容如下:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := catchthrow_jni
LOCAL_SRC_FILES := catchthrow_jni.c LOCAL_LDLIBS := -llog include $(BUILD_SHARED_LIBRARY)
jni/catchthrow/logger.h 主要用来在JNI层打印日志,内容如下:
#include <jni.h>
#include <android/log.h> /**
* 定义log标签
*/
#define TAG "jni_logger" /**
* 定义info信息
*/
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__) /**
* 定义debug信息
*/
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__) /**
* 定义error信息
*/
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
jni/catchthrow/catchthrow_jni.c,主要用来注册绑定java函数和native函数,以及java函数在c中相应函数的具体实现, 内容如下:
#include "logger.h" #ifndef NULL
#define NULL ((void *) 0)
#endif /**
* 获取数组的大小
*/
#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) /**
* 指定要注册的类,对应的完整的java类名
*/
#define JNIREG_CLASS "com/clarck/jni/CatchThrow" /**
* 返回成员实例域
*/
JNIEXPORT void JNICALL native_catchThrow_doit(JNIEnv *env, jobject obj) {
jthrowable exc;
jclass cls = (*env)->GetObjectClass(env, obj);
jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "()V"); if (NULL == mid) {
return ;
}
(*env)->CallVoidMethod(env, obj, mid);
exc = (*env)->ExceptionOccurred(env);
if (exc) {
jclass newExcCls;
(*env)->ExceptionDescribe(env);
(*env)->ExceptionClear(env);
newExcCls = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
if (newExcCls == NULL) {
return ;
}
(*env)->ThrowNew(env, newExcCls, "thrown from C code");
}
} /**
* Java和JNI函数绑定
*/
static JNINativeMethod method_table[] = {
{ "doit", "()V", (void*) native_catchThrow_doit },
}; /**
* 注册native方法到java中
*/
static int registerNativeMethods(JNIEnv* env, const char* className,
JNINativeMethod* gMethods, int numMethods) {
jclass clazz;
clazz = (*env)->FindClass(env, className);
if (clazz == NULL) {
return JNI_FALSE;
} if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < ) {
return JNI_FALSE;
} return JNI_TRUE;
} /**
* 调用注册方法
*/
int register_ndk_load(JNIEnv* env) {
return registerNativeMethods(env, JNIREG_CLASS, method_table,
NELEM(method_table));
} JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env = NULL;
jint result = -; if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
return result;
} register_ndk_load(env); //返回jni的版本
return JNI_VERSION_1_4;
}
接着在Project中右键Android Tools->Add Native Support,最后java层调用如下:
package com.clarck.jni;
public class CatchThrow {
public native void doit() throws IllegalArgumentException;
public void callback() throws NullPointerException {
throw new NullPointerException("CathcThrow.callback");
}
static {
System.loadLibrary("catchthrow_jni");
}
}
package com.clarck.jni; import android.app.Activity;
import android.os.Bundle;
import android.util.Log; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); CatchThrow c = new CatchThrow();
try {
c.doit();
} catch (Exception e) {
Log.d("Test", "In Java: \n \t" + e);
}
}
}
执行Ctrl+B编译,然后运行即可。
Android NDK 学习之在C中抛出异常的更多相关文章
- Android NDK 学习之在C中调用Java的变量和静态变量
本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...
- Android NDK学习总结
一.android NDK编程步骤 java文件中声明native方法. android工程根目录新建jni文件夹. 调用javah命令为第一步声明的native方法生成相应的.h头文件. 通过win ...
- Android NDK学习(2)Windows下NDK开发环境配置
转:http://www.cnblogs.com/fww330666557/archive/2012/12/14/2817386.html 一.配置好Android开发环境 二.下载安装安卓NDK ...
- Android NDK 学习之传递类对象
本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...
- Android NDK学习(一):目录结构解析
我们配置好NDK环境后,基本可以看到其目录结构如下图: 下面我们来分析一下NDK根目录的结构: ndk-build:该Shell脚本是Android NDK构建系统的起始点,一般在项目中仅仅执行这一个 ...
- Android NDK学习(1) 简介
转:http://www.cnblogs.com/fww330666557/archive/2012/12/14/2817385.html 一.What is the NDK? The Android ...
- Android NDK学习记录(一)
一.NDK环境在Mac中部署 1.准备eclipse,android sdk安装包,android ndk安装包(http://dl.google.com/android/ndk/android-nd ...
- Android NDK 学习之调用Java函数
本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...
- Android NDK 学习之接受Java传入Object数组
本博客主要是在Ubuntu 下开发,且默认你已经安装了Eclipse,Android SDK, Android NDK, CDT插件. 在Eclipse中添加配置NDK,路径如下Eclipse-> ...
随机推荐
- Angular常用命令:
新建项目: ng new angualrdermo08 --skip-install 创建需要的组件: ng g component home
- bat批处理文件怎么将路径添加到path环境变量中
bat批处理文件怎么将路径添加到path环境变量中 摘自:https://zhidao.baidu.com/question/1887763143433391788.html 永久性的: @echo ...
- ABAP DEMO ole示例程序
*&---------------------------------------------------------------------* *& Report YCX_021 * ...
- django 中单独执行py文件修改用户名
Python文件代码 import os import django # 在environ字典里设置默认Django环境,'xxxx.settings'指Django项目的配置文件 os.enviro ...
- docker 之网络配置
Docker 网络实现 首先,要实现网络通信,机器需要至少一个网络接口(物理接口或虚拟接口)来收发数据包:此外,如果不同子网之间要进行通信,需要路由机制. Docker 中的网络接口默认都是虚拟的接口 ...
- 【译】Vue源码学习(一):Vue对象构造函数
本系列文章详细深入Vue.js的源代码,以此来说明JavaScript的基本概念,尝试将这些概念分解到JavaScript初学者可以理解的水平.有关本系列的一些后续的计划和轨迹的更多信息,请参阅此文章 ...
- Netty学习笔记(四)——实现dubbo的rpc
1.rpc基本介绍 RPC ( Remote Procedure Call) -远程过程调用,是一个计算机通信协议.该协议允许运行于一台计算机的程序调用另一台计算机的子程序,两个或多个应用程序分布不同 ...
- Python 数据处理库pandas教程(最后附上pandas_datareader使用实例)
0 简单介绍 pandas是一个Python语言的软件包,在我们使用Python语言进行机器学习编程的时候,这是一个非常常用的基础编程库.本文是对它的一个入门教程. pandas提供了快速,灵活和富有 ...
- python安装OpenCV – 4.1.0
(python3) [jiangshan@localhost ~]$ pip install opencv_python==4.1.0Collecting opencv_python==4.1.0 E ...
- [转帖]PCIe 6.0 v0.3版本草案已完稿:2021年转正、x16带宽飙至128GB/s
PCIe 6.0 v0.3版本草案已完稿:2021年转正.x16带宽飙至128GB/s https://www.cnbeta.com/articles/tech/899389.htm 硬件发展突飞猛进 ...